预约功能更新
This commit is contained in:
parent
87e791e853
commit
f5f09c89da
|
@ -202,6 +202,65 @@ class Customers extends EA_Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter customers by the provided keyword.
|
||||||
|
*/
|
||||||
|
public function search_by_phone(): void
|
||||||
|
{
|
||||||
|
|
||||||
|
$phoneNumber = request('phone_number', '');
|
||||||
|
if (empty($phoneNumber)) {
|
||||||
|
// 返回错误信息
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid phone number']);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询数据库中的预约信息
|
||||||
|
$appointments = $this->appointments_model->get_appointments_by_phone($phoneNumber);
|
||||||
|
foreach ($appointments as &$appointment) {
|
||||||
|
$this->appointments_model->load($appointment, ['service', 'provider']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($appointments)) {
|
||||||
|
// 返回预约信息
|
||||||
|
echo json_encode(['success' => true, 'appointments' => $appointments]);
|
||||||
|
} else {
|
||||||
|
// 如果没有找到预约信息
|
||||||
|
echo json_encode(['success' => false, 'message' => 'No appointments found']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cancel(): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$appointmentId = request('appointmentId');
|
||||||
|
|
||||||
|
// 查找指定的预约记录
|
||||||
|
$appointment = $this->appointments_model->find($appointmentId);
|
||||||
|
|
||||||
|
if ($appointment) {
|
||||||
|
// 更新状态为 '取消'
|
||||||
|
$appointment['status'] = '取消';
|
||||||
|
|
||||||
|
// 保存更新后的预约记录
|
||||||
|
$this->appointments_model->save($appointment);
|
||||||
|
|
||||||
|
json_response([
|
||||||
|
'success' => true,
|
||||||
|
'id' => $appointmentId,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// 处理预约记录不存在的情况
|
||||||
|
json_response([
|
||||||
|
'success' => false,
|
||||||
|
'message' => '預約記錄不存在。',
|
||||||
|
], 404);
|
||||||
|
}
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
json_exception($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a new customer.
|
* Store a new customer.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -649,7 +649,7 @@ class Appointments_model extends EA_Model
|
||||||
->like('providers.phone_number', $phone_number)
|
->like('providers.phone_number', $phone_number)
|
||||||
->or_like('customers.phone_number', $phone_number)
|
->or_like('customers.phone_number', $phone_number)
|
||||||
->group_end()
|
->group_end()
|
||||||
->where('appointments.start_datetime >=', date('Y-m-d H:i:s')) // 过滤掉当天00点之前的预约
|
// ->where('appointments.start_datetime >=', date('Y-m-d H:i:s')) // 过滤掉当天00点之前的预约
|
||||||
->limit($limit)
|
->limit($limit)
|
||||||
->offset($offset)
|
->offset($offset)
|
||||||
->order_by($order_by)
|
->order_by($order_by)
|
||||||
|
@ -662,4 +662,5 @@ class Appointments_model extends EA_Model
|
||||||
|
|
||||||
return $appointments;
|
return $appointments;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="<?= config('language_code') ?>">
|
<html lang="<?= config('language_code') ?>">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
@ -7,9 +8,9 @@
|
||||||
<meta name="theme-color" content="#35A768">
|
<meta name="theme-color" content="#35A768">
|
||||||
<meta name="google" content="notranslate">
|
<meta name="google" content="notranslate">
|
||||||
|
|
||||||
<meta property="og:title" content="<?= lang('page_title') . ' ' . vars('company_name') ?> | TFE Group"/>
|
<meta property="og:title" content="<?= lang('page_title') . ' ' . vars('company_name') ?> | TFE Group" />
|
||||||
<meta property="og:url" content="<?= base_url() ?>">
|
<meta property="og:url" content="<?= base_url() ?>">
|
||||||
<meta property="og:image" content="<?= base_url('assets/img/social-card.png') ?>"/>
|
<meta property="og:image" content="<?= base_url('assets/img/social-card.png') ?>" />
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
|
|
||||||
<?php slot('meta'); ?>
|
<?php slot('meta'); ?>
|
||||||
|
@ -38,9 +39,11 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 44.2vh;
|
min-height: 44.2vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container-title {
|
.search-container-title {
|
||||||
color: #666666;
|
color: #666666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container {
|
.search-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -49,6 +52,7 @@
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container input {
|
.search-container input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
@ -56,6 +60,7 @@
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container button {
|
.search-container button {
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
background-color: #429a82;
|
background-color: #429a82;
|
||||||
|
@ -65,12 +70,15 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.appointments-container {
|
.appointments-container {
|
||||||
display: none;
|
display: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
padding: 0 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-appointments {
|
.no-appointments {
|
||||||
display: none;
|
display: none;
|
||||||
color: red;
|
color: red;
|
||||||
|
@ -81,7 +89,7 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="main" class="container">
|
<div id="main" class="container">
|
||||||
<div class="row wrapper">
|
<div class="row wrapper">
|
||||||
<div id="book-appointment-wizard" class="col-12 col-lg-10 col-xl-8 col-xxl-7">
|
<div id="book-appointment-wizard" class="col-12 col-lg-10 col-xl-8 col-xxl-7">
|
||||||
<?php component('home_header', [
|
<?php component('home_header', [
|
||||||
|
@ -108,50 +116,47 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (vars('display_cookie_notice') === '1'): ?>
|
<?php if (vars('display_cookie_notice') === '1'): ?>
|
||||||
<?php component('cookie_notice_modal', ['cookie_notice_content' => vars('cookie_notice_content')]); ?>
|
<?php component('cookie_notice_modal', ['cookie_notice_content' => vars('cookie_notice_content')]); ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (vars('display_terms_and_conditions') === '1'): ?>
|
<?php if (vars('display_terms_and_conditions') === '1'): ?>
|
||||||
<?php component('terms_and_conditions_modal', [
|
<?php component('terms_and_conditions_modal', [
|
||||||
'terms_and_conditions_content' => vars('terms_and_conditions_content'),
|
'terms_and_conditions_content' => vars('terms_and_conditions_content'),
|
||||||
]); ?>
|
]); ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (vars('display_privacy_policy') === '1'): ?>
|
<?php if (vars('display_privacy_policy') === '1'): ?>
|
||||||
<?php component('privacy_policy_modal', ['privacy_policy_content' => vars('privacy_policy_content')]); ?>
|
<?php component('privacy_policy_modal', ['privacy_policy_content' => vars('privacy_policy_content')]); ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<script src="<?= asset_url('assets/vendor/jquery/jquery.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/jquery/jquery.min.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/vendor/cookieconsent/cookieconsent.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/cookieconsent/cookieconsent.min.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/vendor/@popperjs-core/popper.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/@popperjs-core/popper.min.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/vendor/bootstrap/bootstrap.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/bootstrap/bootstrap.min.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/vendor/moment/moment.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/moment/moment.min.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/vendor/moment-timezone/moment-timezone-with-data.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/moment-timezone/moment-timezone-with-data.min.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/fontawesome.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/fontawesome.min.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/solid.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/@fortawesome-fontawesome-free/solid.min.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/vendor/tippy.js/tippy-bundle.umd.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/tippy.js/tippy-bundle.umd.min.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/vendor/flatpickr/flatpickr.min.js') ?>"></script>
|
<script src="<?= asset_url('assets/vendor/flatpickr/flatpickr.min.js') ?>"></script>
|
||||||
|
|
||||||
<script src="<?= asset_url('assets/js/app.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/app.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/date.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/utils/file.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/file.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/utils/http.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/http.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/utils/lang.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/lang.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/message.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/utils/string.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/string.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/url.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/utils/validation.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/layouts/booking_layout.js') ?>"></script>
|
<script src="<?= asset_url('assets/js/http/localization_http_client.js') ?>"></script>
|
||||||
<script src="<?= asset_url('assets/js/http/localization_http_client.js') ?>"></script>
|
|
||||||
|
|
||||||
<script src="<?= asset_url('assets/js/http/customers_search_http_client.js') ?>"></script>
|
|
||||||
<script src="<?= asset_url('assets/js/pages/customers.js') ?>"></script>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('searchButton').addEventListener('click', function() {
|
function doSearch() {
|
||||||
var phoneNumber = document.getElementById('phoneNumber').value;
|
var phoneNumber = document.getElementById('phoneNumber').value;
|
||||||
|
|
||||||
if (phoneNumber.trim() === '') {
|
if (phoneNumber.trim() === '') {
|
||||||
|
@ -160,28 +165,50 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送请求前获取CSRF token
|
// 发送请求前获取CSRF token
|
||||||
var csrfToken = document.querySelector('meta[name="csrf_token"]').getAttribute('content');
|
//var csrfToken = document.querySelector('meta[name="csrf_token"]').getAttribute('content');
|
||||||
|
|
||||||
|
const url = App.Utils.Url.siteUrl('customers/search_by_phone');
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
csrf_token: vars('csrf_token'),
|
||||||
|
phone_number: phoneNumber,
|
||||||
|
};
|
||||||
|
|
||||||
|
$.post(url, data).done((response) => {
|
||||||
|
// console.log('data',typeof(data));
|
||||||
|
const data = JSON.parse(response);
|
||||||
|
|
||||||
fetch('/index.php/appointmentSearch/search_by_phone', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-CSRF-TOKEN': csrfToken // 添加CSRF Token到请求头
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ phone_number: phoneNumber })
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.success && data.appointments.length > 0) {
|
if (data.success && data.appointments.length > 0) {
|
||||||
displayAppointments(data.appointments);
|
displayAppointments(data.appointments);
|
||||||
} else {
|
} else {
|
||||||
showNoAppointmentsMessage();
|
showNoAppointmentsMessage();
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error fetching appointments:', error);
|
|
||||||
showNoAppointmentsMessage();
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('searchButton').addEventListener('click', function() {
|
||||||
|
|
||||||
|
doSearch();
|
||||||
|
// fetch('/index.php/customers/search_by_phone', {
|
||||||
|
// method: 'POST',
|
||||||
|
// headers: {
|
||||||
|
// 'Content-Type': 'application/json',
|
||||||
|
// //'X-CSRF-TOKEN': csrfToken // 添加CSRF Token到请求头
|
||||||
|
// },
|
||||||
|
// body: formData
|
||||||
|
// })
|
||||||
|
// .then(response => response.json())
|
||||||
|
// .then(data => {
|
||||||
|
// if (data.success && data.appointments.length > 0) {
|
||||||
|
// displayAppointments(data.appointments);
|
||||||
|
// } else {
|
||||||
|
// showNoAppointmentsMessage();
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .catch(error => {
|
||||||
|
// console.error('Error fetching appointments:', error);
|
||||||
|
// showNoAppointmentsMessage();
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
function displayAppointments(appointments) {
|
function displayAppointments(appointments) {
|
||||||
|
@ -191,7 +218,66 @@
|
||||||
appointmentsList.innerHTML = '';
|
appointmentsList.innerHTML = '';
|
||||||
appointments.forEach(function(appointment) {
|
appointments.forEach(function(appointment) {
|
||||||
var listItem = document.createElement('li');
|
var listItem = document.createElement('li');
|
||||||
listItem.textContent = `预约时间:${appointment.start_datetime},提供者ID:${appointment.id_users_provider}`;
|
|
||||||
|
// 创建服务名称和提供者姓名的 div
|
||||||
|
var serviceDiv = document.createElement('div');
|
||||||
|
serviceDiv.textContent = `${appointment.service.name} - ${appointment.provider.last_name}${appointment.provider.first_name}`;
|
||||||
|
|
||||||
|
// 创建预约时间的 div
|
||||||
|
var timeDiv = document.createElement('div');
|
||||||
|
timeDiv.textContent = `開始時間:${appointment.start}`;
|
||||||
|
|
||||||
|
// 创建结束时间的 div
|
||||||
|
var endDiv = document.createElement('div');
|
||||||
|
endDiv.textContent = `結束時間:${appointment.end}`;
|
||||||
|
|
||||||
|
// 创建状态的 div
|
||||||
|
var statusDiv = document.createElement('div');
|
||||||
|
statusDiv.textContent = `狀態:${appointment.status}`;
|
||||||
|
|
||||||
|
// 将每个 div 添加到 li 中
|
||||||
|
listItem.appendChild(serviceDiv);
|
||||||
|
listItem.appendChild(timeDiv);
|
||||||
|
listItem.appendChild(endDiv);
|
||||||
|
listItem.appendChild(statusDiv);
|
||||||
|
|
||||||
|
// 如果状态是“已预约”,添加取消预约按钮
|
||||||
|
if (appointment.status === '已預約') {
|
||||||
|
var cancelButton = document.createElement('button');
|
||||||
|
cancelButton.textContent = '取消預約';
|
||||||
|
cancelButton.className = 'btn btn-danger'; // 添加一些样式类名
|
||||||
|
cancelButton.addEventListener('click', function() {
|
||||||
|
// 确认对话框
|
||||||
|
var confirmCancel = confirm('您確定要取消這個預約嗎?');
|
||||||
|
|
||||||
|
if (confirmCancel) {
|
||||||
|
// 添加取消预约的逻辑
|
||||||
|
// 例如,发起一个请求到服务器取消预约
|
||||||
|
console.log(`取消預約:${appointment.id}`);
|
||||||
|
// 这里可以添加实际的请求代码
|
||||||
|
const url = App.Utils.Url.siteUrl('customers/cancel');
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
csrf_token: vars('csrf_token'),
|
||||||
|
appointmentId: appointment.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
$.post(url, data).done((data) => {
|
||||||
|
// console.log('data',response);
|
||||||
|
if (data.success) {
|
||||||
|
//重新加载
|
||||||
|
doSearch();
|
||||||
|
alert('取消預約成功。');
|
||||||
|
} else {
|
||||||
|
alert('取消預約失敗。');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
listItem.appendChild(cancelButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 li 添加到 ul 或 ol 列表中
|
||||||
appointmentsList.appendChild(listItem);
|
appointmentsList.appendChild(listItem);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -203,18 +289,19 @@
|
||||||
document.getElementById('appointmentsContainer').style.display = 'none';
|
document.getElementById('appointmentsContainer').style.display = 'none';
|
||||||
document.getElementById('noAppointmentsMessage').style.display = 'block';
|
document.getElementById('noAppointmentsMessage').style.display = 'block';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<?php component('js_vars_script'); ?>
|
<?php component('js_vars_script'); ?>
|
||||||
<?php component('js_lang_script'); ?>
|
<?php component('js_lang_script'); ?>
|
||||||
|
|
||||||
<?php component('google_analytics_script', ['google_analytics_code' => vars('google_analytics_code')]); ?>
|
<?php component('google_analytics_script', ['google_analytics_code' => vars('google_analytics_code')]); ?>
|
||||||
<?php component('matomo_analytics_script', [
|
<?php component('matomo_analytics_script', [
|
||||||
'matomo_analytics_url' => vars('matomo_analytics_url'),
|
'matomo_analytics_url' => vars('matomo_analytics_url'),
|
||||||
'matomo_analytics_site_id' => vars('matomo_analytics_site_id'),
|
'matomo_analytics_site_id' => vars('matomo_analytics_site_id'),
|
||||||
]); ?>
|
]); ?>
|
||||||
|
|
||||||
<?php slot('scripts'); ?>
|
<?php slot('scripts'); ?>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
Binary file not shown.
Loading…
Reference in New Issue