Feat: Выбор типа получателя в заявке
✅ Select: Пользователь/Группа/Организация ✅ Динамическое переключение полей ✅ Валидация выбора получателя ✅ Убрано поле Организация из info блока Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
3f0039712d
commit
b313d96bfc
|
|
@ -80,9 +80,14 @@ class CourseRequestController extends Controller
|
||||||
DB::beginTransaction();
|
DB::beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Берём organization_id из первого элемента или null
|
// Берём organization_id из ПЕРВОГО элемента у которого он есть
|
||||||
$firstItem = reset($items);
|
$organizationId = null;
|
||||||
$organizationId = $firstItem['organization_id'] ?? null;
|
foreach ($items as $item) {
|
||||||
|
if (!empty($item['organization_id'])) {
|
||||||
|
$organizationId = $item['organization_id'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Создаём заявку
|
// Создаём заявку
|
||||||
$courseRequest = CourseRequest::create([
|
$courseRequest = CourseRequest::create([
|
||||||
|
|
|
||||||
|
|
@ -79,23 +79,32 @@
|
||||||
<select id="element_course_id" class="form-select" required></select>
|
<select id="element_course_id" class="form-select" required></select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Строка 2: Получатели -->
|
<!-- Строка 2: Тип получателя -->
|
||||||
<div class="col-md-4">
|
<div class="col-md-12">
|
||||||
<label class="form-label">Организация</label>
|
<label class="form-label">Тип получателя *</label>
|
||||||
<select id="element_organization_id" class="form-select"></select>
|
<select id="element_recipient_type" class="form-select" onchange="toggleRecipientFields()">
|
||||||
<small class="text-muted">И</small>
|
<option value="">Выберите тип</option>
|
||||||
</div>
|
<option value="user">Пользователь</option>
|
||||||
<div class="col-md-4">
|
<option value="group">Группа</option>
|
||||||
<label class="form-label">Группа</label>
|
<option value="organization">Организация</option>
|
||||||
<select id="element_group_ids" multiple></select>
|
</select>
|
||||||
<small class="text-muted">И</small>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<label class="form-label">Пользователь</label>
|
|
||||||
<select id="element_user_ids" multiple></select>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Строка 3: Даты -->
|
<!-- Строка 3: Получатели (динамические поля) -->
|
||||||
|
<div class="col-md-12" id="recipient_user_field" style="display:none;">
|
||||||
|
<label class="form-label">Пользователь *</label>
|
||||||
|
<select id="element_user_ids" multiple></select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12" id="recipient_group_field" style="display:none;">
|
||||||
|
<label class="form-label">Группа *</label>
|
||||||
|
<select id="element_group_ids" multiple></select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12" id="recipient_organization_field" style="display:none;">
|
||||||
|
<label class="form-label">Организация *</label>
|
||||||
|
<select id="element_organization_id" class="form-select"></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Строка 4: Даты -->
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label">Дата начала *</label>
|
<label class="form-label">Дата начала *</label>
|
||||||
<input type="date" id="element_start_date" class="form-control" required>
|
<input type="date" id="element_start_date" class="form-control" required>
|
||||||
|
|
@ -127,6 +136,14 @@ let elementCounter = 0;
|
||||||
let courseSelect = null, orgSelect = null, groupTags = null, userTags = null;
|
let courseSelect = null, orgSelect = null, groupTags = null, userTags = null;
|
||||||
let modalInitialized = false;
|
let modalInitialized = false;
|
||||||
|
|
||||||
|
// Переключение полей получателей
|
||||||
|
window.toggleRecipientFields = function() {
|
||||||
|
const type = document.getElementById('element_recipient_type').value;
|
||||||
|
document.getElementById('recipient_user_field').style.display = (type === 'user') ? 'block' : 'none';
|
||||||
|
document.getElementById('recipient_group_field').style.display = (type === 'group') ? 'block' : 'none';
|
||||||
|
document.getElementById('recipient_organization_field').style.display = (type === 'organization') ? 'block' : 'none';
|
||||||
|
};
|
||||||
|
|
||||||
// Инициализация TomSelect при ПЕРВОМ открытии modal
|
// Инициализация TomSelect при ПЕРВОМ открытии modal
|
||||||
document.getElementById('addElementModal').addEventListener('show.bs.modal', function() {
|
document.getElementById('addElementModal').addEventListener('show.bs.modal', function() {
|
||||||
if (modalInitialized) return;
|
if (modalInitialized) return;
|
||||||
|
|
@ -217,9 +234,7 @@ document.getElementById('addElementModal').addEventListener('hidden.bs.modal', f
|
||||||
// Добавление элемента
|
// Добавление элемента
|
||||||
document.getElementById('addElementBtn').addEventListener('click', function() {
|
document.getElementById('addElementBtn').addEventListener('click', function() {
|
||||||
const courseId = courseSelect.getValue();
|
const courseId = courseSelect.getValue();
|
||||||
const organizationId = orgSelect.getValue();
|
const recipientType = document.getElementById('element_recipient_type').value;
|
||||||
const groupIds = groupTags.getValue() || [];
|
|
||||||
const userIds = userTags.getValue() || [];
|
|
||||||
const startDate = document.getElementById('element_start_date').value;
|
const startDate = document.getElementById('element_start_date').value;
|
||||||
const endDate = document.getElementById('element_end_date').value;
|
const endDate = document.getElementById('element_end_date').value;
|
||||||
|
|
||||||
|
|
@ -228,32 +243,65 @@ document.getElementById('addElementBtn').addEventListener('click', function() {
|
||||||
alert('Выберите курс');
|
alert('Выберите курс');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!recipientType) {
|
||||||
|
alert('Выберите тип получателя');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!startDate) {
|
if (!startDate) {
|
||||||
alert('Укажите дату начала');
|
alert('Укажите дату начала');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Получаем названия
|
// Получаем выбранных получателей в зависимости от типа
|
||||||
|
let organizationId = null, organizationName = null;
|
||||||
|
let groupIds = [], groupNames = [];
|
||||||
|
let userIds = [], userNames = [];
|
||||||
|
|
||||||
|
if (recipientType === 'user') {
|
||||||
|
userIds = userTags.getValue() || [];
|
||||||
|
if (!userIds || (Array.isArray(userIds) && userIds.length === 0)) {
|
||||||
|
alert('Выберите хотя бы одного пользователя');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
userIds = Array.isArray(userIds) ? userIds : [userIds];
|
||||||
|
userNames = userIds.map(id => {
|
||||||
|
const opt = userTags.options[id];
|
||||||
|
return opt ? opt.text : 'Пользователь #' + id;
|
||||||
|
}).filter(Boolean);
|
||||||
|
} else if (recipientType === 'group') {
|
||||||
|
groupIds = groupTags.getValue() || [];
|
||||||
|
if (!groupIds || (Array.isArray(groupIds) && groupIds.length === 0)) {
|
||||||
|
alert('Выберите хотя бы одну группу');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
groupIds = Array.isArray(groupIds) ? groupIds : [groupIds];
|
||||||
|
groupNames = groupIds.map(id => {
|
||||||
|
const opt = groupTags.options[id];
|
||||||
|
return opt ? opt.text : 'Группа #' + id;
|
||||||
|
}).filter(Boolean);
|
||||||
|
} else if (recipientType === 'organization') {
|
||||||
|
organizationId = orgSelect.getValue();
|
||||||
|
if (!organizationId) {
|
||||||
|
alert('Выберите организацию');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const orgOption = orgSelect.options[organizationId];
|
||||||
|
organizationName = orgOption ? orgOption.text : null;
|
||||||
|
}
|
||||||
|
|
||||||
const courseOption = courseSelect.options[courseId];
|
const courseOption = courseSelect.options[courseId];
|
||||||
const orgOption = organizationId ? orgSelect.options[organizationId] : null;
|
|
||||||
|
|
||||||
// Добавляем элемент
|
// Добавляем элемент
|
||||||
items.push({
|
items.push({
|
||||||
id: elementCounter++,
|
id: elementCounter++,
|
||||||
course_id: courseId,
|
course_id: courseId,
|
||||||
course_name: courseOption ? courseOption.text : 'Курс #' + courseId,
|
course_name: courseOption ? courseOption.text : 'Курс #' + courseId,
|
||||||
organization_id: organizationId || null,
|
organization_id: organizationId,
|
||||||
organization_name: orgOption ? orgOption.text : null,
|
organization_name: organizationName,
|
||||||
group_ids: Array.isArray(groupIds) ? groupIds : [groupIds],
|
group_ids: groupIds,
|
||||||
group_names: (Array.isArray(groupIds) ? groupIds : [groupIds]).map(id => {
|
group_names: groupNames,
|
||||||
const opt = groupTags.options[id];
|
user_ids: userIds,
|
||||||
return opt ? opt.text : 'Группа #' + id;
|
user_names: userNames,
|
||||||
}).filter(Boolean),
|
|
||||||
user_ids: Array.isArray(userIds) ? userIds : [userIds],
|
|
||||||
user_names: (Array.isArray(userIds) ? userIds : [userIds]).map(id => {
|
|
||||||
const opt = userTags.options[id];
|
|
||||||
return opt ? opt.text : 'Пользователь #' + id;
|
|
||||||
}).filter(Boolean),
|
|
||||||
start_date: startDate,
|
start_date: startDate,
|
||||||
end_date: endDate || null
|
end_date: endDate || null
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@
|
||||||
<div class="card shadow-sm">
|
<div class="card shadow-sm">
|
||||||
<div class="card-header bg-primary text-white"><h5 class="mb-0">Информация</h5></div>
|
<div class="card-header bg-primary text-white"><h5 class="mb-0">Информация</h5></div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div><strong>Организация:</strong> {{ $courseRequest->organization?->name ?? 'Без организации' }}</div>
|
|
||||||
<div><strong>Статус:</strong>
|
<div><strong>Статус:</strong>
|
||||||
@if($courseRequest->isPending())
|
@if($courseRequest->isPending())
|
||||||
<span class="badge bg-warning">Ожидает</span>
|
<span class="badge bg-warning">Ожидает</span>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue