Перейти к содержимому



Таблица записи на прием.

#1 gaaarfild

gaaarfild
  • Пользователь
  • 596 сообщений
  • Репутация: 0
0

Отправлено 01 Апрель 2011 - 00:34

Есть такая задача.
Есть несколько докторов.
На одной странице для каждого доктора загружается своя таблица. Все на одной странице.
В таблице время с периодичностью в 15 минут. от 8 часов до 23. Например 8:00 8:15 8:30 и так далее.
Из базы данных вытаскивается доктор, и для него строится таблица. и так в цикле для каждого.
А таблица сама делается двойным вложенным циклом. Один для часов, другой для минут.
Но, когда есть записи на определенное время, как сделать наиболее оптимизированно, чтобы в тех ячейках, где запись есть, она отобразилась?
У меня получилось пока только запрос в цикле запросов.
Все даты хранятся в unixtime.

 

 

  • 0

robot

robot
  • Пользователь PRO
  • 2 652 сообщений
  • Репутация: 85
Советую обратить внимание на следующее:
  1. Почему размножаются записи в таблице MySQL
  2. Идентификатор последней записи в таблице
  3. Количество записей в таблице

#2 surfer

surfer
  • Заблокированные
  • 1 956 сообщений
  • Репутация: 71

Отправлено 01 Апрель 2011 - 07:53

а почему вложенныи цикламе, мне кажется одного цикла достаточно.
все зависит от структуры таблиц, приведи их структуру здесь.
  • 0

#3 gaaarfild

gaaarfild
    Topic Starter
  • Пользователь
  • 596 сообщений
  • Репутация: 0

Отправлено 01 Апрель 2011 - 12:09

Структуру каких таблиц? HTML или таблиц БД?
  • 0

#4 surfer

surfer
  • Заблокированные
  • 1 956 сообщений
  • Репутация: 71

Отправлено 01 Апрель 2011 - 12:37

обоих
  • 0

#5 gaaarfild

gaaarfild
    Topic Starter
  • Пользователь
  • 596 сообщений
  • Репутация: 0

Отправлено 01 Апрель 2011 - 13:17

Вот вся функция

function Schedule() {
global $db, $db, $prefix, $config, $templ, $users_class, $texts_class;
$this->menu();
$templ->page_title = 'Запись на прием - Таблица приема';
$templ->page_head_title = 'Запись на прием » Таблица приема';
if(isset($_GET["date"]))
{
$year = (int)substr($_GET['date'], 0, 4);
$month = (int)substr($_GET['date'], 4, 2);
$day = (int)substr($_GET['date'], 6, 2);
}
else // иначе выводить текущие месяц и год
{
$day = date('d', mktime(0,0,0,date('m'),date('d'),date('Y')));
$month = date('m', mktime(0,0,0,date('m'),date('d'),date('Y')));
$year = date('Y', mktime(0,0,0,date('m'),date('d'),date('Y')));
}

$result = $db->sql_query("SELECT a.id, a.name, a.surname, b.title FROM ".$prefix."_users a, ".$prefix."_user_posts b WHERE a.post=b.id AND b.doctor=1 AND a.arch!=1 ORDER BY a.surname ASC");
$count = $db->sql_numrows();
echo '<div style="width: 447px;" id="tools_panel">
&nbsp;&nbsp;&nbsp;&nbsp;<b><a href="index.php?mod=appointments&do=Schedule&date='.date("Ymd", mktime(0,0,0,$month,$day-1,$year)).'">«</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="index.php?mod=appointments&do=Schedule">Сегодня</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="index.php?mod=appointments&do=Schedule&date='.date("Ymd", mktime(0,0,0,$month,$day+1,$year)).'">»</a></b>&nbsp;&nbsp;&nbsp;&nbsp;<b>Дата:</b> <u>'.$texts_class->date2rus(date('d F Y', mktime(0,0,0,$month,$day,$year))).'</u>&nbsp;&nbsp;&nbsp;&nbsp;<b>'.$texts_class->day2rus(date('l', mktime(0,0,0,$month,$day,$year))).'</b>
</div>';
while(list($id, $first_name, $second_name, $user_post) = $db->sql_fetchrow($result)) {
$name = $second_name.' '.$texts_class->short_text($first_name, 1).'.';
$result2 = $db->sql_query("SELECT pa.start_time, pa.end_time, pa.status, p.second_name, wt.title FROM ".$prefix."_patients_appointment pa, ".$prefix."_patients p, ".$prefix."_work_types wt, ".$prefix."_work_type_types wtt, ".$prefix."_work_divisions wd WHERE pa.doctor_id=".$id." AND pa.patient_id=p.id AND pa.work_type=wt.id AND wt.div=wd.id AND wt.types=wtt.id AND (pa.start_time BETWEEN ".mktime(1,1,1,$month,$day,$year)." AND ".mktime(0,0,0,$month,$day+1,$year).") ORDER BY pa.start_time ASC");
echo '<table border="0" cellpadding="0" cellspacing="1" style="float: left;" class="schedule_table">
<tr>
<th colspan="2">
'.$name.'<br /><span style="font-weight: normal;font-size: 10px;">'.$user_post.'</span>
</th>
</tr>';
for($h=8; $h<23; $h++) {
for($m=0; $m<=45; ) {
echo '<tr><td align="right" style="padding: 0 6px 0 6px;width: 30px;'.($m==0 ? 'font-weight: bold;background: #C8FFD7;border-top: 1px solid #777777;' : '').'">'.$h.':'.($m==0 ? '00' : $m).'</td><td style="width: 94px;cursor:pointer;padding: 0 3px 0 3px;'.($m==0 ? 'font-weight: bold;background: #C8FFD7;border-top: 1px solid #777777;' : '').'" title="'.date('H:i:s d.m.Y', mktime($h,$m,1,$month,$day,$year)).'" onclick=\'show_dialog_ajax_t("#appoint_block", "mod=appointments&do=add_appoint&doctor='.$id.'&time='.mktime($h,$m,1,$month,$day,$year).'", "Запись на прием '.date('H:i d.m.Y', mktime($h,$m,1,$month,$day,$year)).'")\'>';
while(list($start_time, $end_time, $status, $second_name, $work_type) = $db->sql_fetchrow($result2)) {
$timme = mktime($h,$m,1,$month,$day,$year);
if($timme >= $start_time && $timme <= $end_time) echo $second_name;
}
echo '</td></tr>';
$m += 15;
}
}
echo '</table>';
}
echo '<div class="clear"></div><div id="appoint_block"></div>';
}


И это явно очень кривая реализация, как минимум потому, что не работает.
И это все я написал =))
  • 0

#6 surfer

surfer
  • Заблокированные
  • 1 956 сообщений
  • Репутация: 71

Отправлено 01 Апрель 2011 - 18:42

может таблицу со временем в БД сделать с id и тогда привязать прием можно?
  • 0

#7 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 01 Апрель 2011 - 21:03

gaaarfild, запутался в твоих словах. Покажи на скринах структурц таблицы докторов и таблицы записей. Не очень пока понятно, что нужно сделать...
  • 0

#8 gaaarfild

gaaarfild
    Topic Starter
  • Пользователь
  • 596 сообщений
  • Репутация: 0

Отправлено 01 Апрель 2011 - 21:07

doc_table.png

Вот таблица, которая получается в результате работы скрипта.

Просто есть еще одна особенность, думаю необходимо ее упомянуть. Если время на прием ставится больше 15 минут. Например 1 час, то должны быть заняты 4 ячейки, как и подобает.
  • 0

#9 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 02 Апрель 2011 - 15:51

gaaarfild, хех... Посмотрел на запросы, в одном используется 2 таблицы, в другом 5 таблиц... Проблема не в выводе данных в двойном цикле, а большая проблема, что ты запросы делаешь в цикле. Ну чтож попытаюсь разобраться:
1) Как я понял, в первой таблице идет запрос к таблице пользователей (доктора + ещё кто-то, возможно персонал или пользователи) и к таблице данных о пользователе. Мы вытаскиваем id пользователя(доктора), имя пользователя(доктора), фамилию пользователя(доктора), его род деятельности (ортопед и т.д.), по условию что пользователь - доктор И пользователь не в архиве.
2) во второй таблице вытаскиваются данные о направлениях (Начало приема, окончание приема, статус приема, имя пациента, форма(тип) работы с пациентом)

Тебе нужно:
1) Вытащить всех докторов в какой-нить массив
2) Затем в этот массив по докторам добавлять направления
$doctors = array(
[id_доктора1] => array(
"info" => array('данные доктора1 из первого запроса'),
"appointments" => array(
array('направление1 к доктору1 из второго запроса'),
array('направление2 к доктору1 из второго запроса'),
...
array('направлениеN к доктору1 из второго запроса')
)
),
[id_доктора2] => array(
"info" => array('данные доктора2 из первого запроса'),
"appointments" => array(
array('направление1 к доктору2 из второго запроса'),
array('направление2 к доктору2 из второго запроса'),
...
array('направлениеN к доктору2 из второго запроса')
)
),
...
);


Как обрабатывать сформированные мною данные:
<?php

...

foreach($doctors as $doctor)
{
$first_ch_name = $texts_class->short_text($doctor['info']['name'], 1);
$name_doctor = "{$doctor['info']['surname']} {$first_ch_name}.";

echo '<table border="0" cellpadding="0" cellspacing="1" style="float: left;" class="schedule_table">
<tr>
<th colspan="2">
'.$name_doctor.'<br /><span style="font-weight: normal;font-size: 10px;">'. $doctor['info']['title'] .'</span>
</th>
</tr>';

$hours = 8;
$minuts = 0;

while( $hours != 23 )
{
$time_interval = mktime($hours, $minuts, 1, $month, $day, $year); // время для сравнения направлений

$display_hours = ( $hours < 10 ) ? "0{$hours}" : $hours; // выводимые часы
$display_minuts = ( $minuts < 10 ) ? "0{$minuts}" : $minuts; // выводимые минуты
$display_date_with_sec = date('H:i:s d.m.Y', mktime($hours, $minuts, 1, $month, $day, $year));
$display_date_without_sec = date('H:i d.m.Y', mktime($hours, $minuts, 1, $month, $day, $year));
$display_time = mktime($hours, $minuts, 1, $month, $day, $year);
$onclick = "show_dialog_ajax_t(\"#appoint_block\", \"mod=appointments&do=add_appoint&doctor={$doctor['info']['id']}&time={$display_time}\", \"Запись на прием {$display_date_without_sec}\")";
$class_aliquot = ( $minuts == 0 ) ? " aliquot" : "";

// вывод направлений
echo "<tr>
<td class='date_standart{$class_aliquot}'>
{$display_hours}
</td>
<td class='pacient_standart{$class_aliquot}' title='{$display_date_with_sec}' onclick='{$onclick}'>";

if( count($doctor['appointments']) )
foreach($doctor['appointments'] as $appointment)
if( $appointment['start_time'] <= $time_interval && $appointment['end_time'] >= $time_interval )
{
echo $appointment['second_name'];
break;
}

echo " </td>
</tr>";

// обработка времени
$minuts += 15;
if( $minuts == 60 )
{
$hours += 1;
$minuts = 0;
}
}

echo "</table>";
}
?>


Далее в CSS вынес бы все в классы, а то стили мешают восприятию:
.date_standart {
   padding: 0 6px;
   width: 30px;
   text-align: right;
}

.pacient_standart {
   width: 94px;
   cursor: pointer;
   padding: 0 3px;
}

.aliquot {
   font-weight: bold;
   background: #C8FFD7;
   border-top: 1px solid #777777;
}

А твой скрипт и вправду не будет работать. Так как у тебя идет обход цикла часов и обход цикла минут, а запрос производится один раз.
Заметим, что после прохода по всем записям запроса один раз, указатель установится вконец и while твой, будет всегда возвращать false
  • 0

#10 gaaarfild

gaaarfild
    Topic Starter
  • Пользователь
  • 596 сообщений
  • Репутация: 0

Отправлено 02 Апрель 2011 - 16:19

Спасибо большое.
Отпишусь, как реализую.
  • 0

robot

robot
  • Пользователь PRO
  • 2 652 сообщений
  • Репутация: 85


Оформление форума – IPBSkins.ru