обновлена форма добавления клиентов: сделан выбор нескольких жк

This commit is contained in:
developer 2026-04-15 12:05:55 +08:00
parent e7a11d356c
commit ee64915afc
5 changed files with 140 additions and 89 deletions

View File

@ -21,8 +21,8 @@ class ClientCreateLivewire extends Component
public $complexes;
public $maxContactsCount;
public $maxContactPhonesCount;
/////////////////////
public $selectedObjects = [];
public $agentId;
public $contacts;
public $objects = [];
@ -36,23 +36,24 @@ class ClientCreateLivewire extends Component
protected function rules()
{
return [
'contacts.*' => ['required', 'min:1'],
'contacts.*.firstName' => ['required', 'string', 'max:50'],
'contacts.*' => ['required', 'min:1'],
'contacts.*.firstName' => ['required', 'string', 'max:50'],
'contacts.*.secondName' => ['required', 'string', 'max:50'],
'contacts.*.phones.*' => 'required|string|regex:/^(\+7)([(]{1})([0-9]{3})([)]{1})([\s]{1})([0-9]{3})([-]{1})([0-9]{2})([-]{1})([0-9]{2})/',
'complexId' => ['required'],
'agentId' => ['required'],
'contacts.*.phones.*' => 'required|string|regex:/^(\+7)([(]{1})([0-9]{3})([)]{1})([\s]{1})([0-9]{3})([-]{1})([0-9]{2})([-]{1})([0-9]{2})/',
'selectedObjects' => 'required',
'agentId' => ['required'],
];
}
protected function messages()
{
return [
'contacts.*.firstName.reqired' => 'Необходимо указать имя (отчество) клиента',
'contacts.*.firstName.reqired' => 'Необходимо указать имя (отчество) клиента',
'contacts.*.secondName.reqired' => 'Необходимо указать фамилию клиента',
'contacts.*.firstName.max' => 'Указанное имя клиента слишком длинное',
'contacts.*.secondName.max' => 'Указанное имя клиента слишком длинное',
'contacts.*.phones.*.reqired' => 'Необходимо указать номер телефона клиента',
'contacts.*.phones.*.regex' => 'Указанный номер телефона некорректный',
'contacts.*.firstName.max' => 'Указанное имя клиента слишком длинное',
'contacts.*.secondName.max' => 'Указанное имя клиента слишком длинное',
'contacts.*.phones.*.reqired' => 'Необходимо указать номер телефона клиента',
'contacts.*.phones.*.regex' => 'Указанный номер телефона некорректный',
'selectedObjects.required' => 'Необходимо выбрать хотя бы один интересующий ЖК',
];
}
@ -63,23 +64,23 @@ public function mount()
$this->availableAgents = GetAvailableAgents();
$this->maxContactPhonesCount = 1;
$this->contacts = [];
$this->contactLabels = ['Основной контакт', 'Супруг/супруга'];
if( array_key_exists('contact_form_count_max', DESIGN_PARAMETERS) && (int)DESIGN_PARAMETERS['contact_form_count_max'] > 0) {
$this->maxContactsCount = (int)DESIGN_PARAMETERS['contact_form_count_max'];
if (array_key_exists('contact_form_count_max', DESIGN_PARAMETERS) && (int) DESIGN_PARAMETERS['contact_form_count_max'] > 0) {
$this->maxContactsCount = (int) DESIGN_PARAMETERS['contact_form_count_max'];
} else {
$this->maxContactsCount = 2;
};
$this->maxContactsCount = 2;
}
if( array_key_exists('contact_form_count', DESIGN_PARAMETERS) && (int)DESIGN_PARAMETERS['contact_form_count'] > 0) {
for ($tabsCount = 1; $tabsCount <= (int)DESIGN_PARAMETERS['contact_form_count']; $tabsCount++) {
if (array_key_exists('contact_form_count', DESIGN_PARAMETERS) && (int) DESIGN_PARAMETERS['contact_form_count'] > 0) {
for ($tabsCount = 1; $tabsCount <= (int) DESIGN_PARAMETERS['contact_form_count']; $tabsCount++) {
$this->addContact();
}
} else {
$this->addContact();
$this->addContact();//по-умолчанию сразу выводить супруга
};
}
$this->contactLabels = ['Основной контакт', 'Супруг/супруга'];
if (count($this->availableAgents) == 1) //чтобы не выводить в форму
{ //и не заставлять пользователя указывать вручную
$this->agentId = $this->availableAgents[0]['id'];
@ -95,16 +96,14 @@ public function mount()
*/
public function addContact()
{
if (!isset($this->contacts))
{
if (!isset($this->contacts)) {
$this->contacts = [];
}
if ($this->maxContactsCount > count($this->contacts))
{
if ($this->maxContactsCount > count($this->contacts)) {
$this->contacts[] = [
'firstName' => '',
'firstName' => '',
'secondName' => '',
'phones' => ['']
'phones' => ['']
];
}
$this->setCurrentContactIndex(count($this->contacts) - 1);
@ -117,12 +116,10 @@ public function addContact()
*/
public function deleteContact($index = false)
{
if ($index === false)
{
if ($index === false) {
$index = $this->currentContactIndex;
}
if ($index > 0)
{
if ($index > 0) {
unset($this->contacts[$index]);
$this->contacts = array_values($this->contacts);
$this->setCurrentContactIndex($index - 1);
@ -145,14 +142,10 @@ public function setCurrentContactIndex($index)
*/
public function toggleSecondContact()
{
if ($this->currentContactIndex == 0)
{
if (count($this->contacts) == 2)
{
if ($this->currentContactIndex == 0) {
if (count($this->contacts) == 2) {
$this->deleteContact(1);
}
elseif (count($this->contacts) == 1)
{
} elseif (count($this->contacts) == 1) {
$this->addContact();
}
}
@ -164,8 +157,7 @@ public function toggleSecondContact()
*/
public function addPhoneForCurrentContact()
{
if (count($this->contacts[$this->currentContactIndex]['phones']) < $this->maxContactPhonesCount)
{
if (count($this->contacts[$this->currentContactIndex]['phones']) < $this->maxContactPhonesCount) {
$this->contacts[$this->currentContactIndex]['phones'][] = '';
}
}
@ -173,22 +165,27 @@ public function updated($propertyName)
{
$this->status = FormStatus::IN_PROCESS;
$this->validateOnly($propertyName);
foreach ($this->selectedObjects as $complexId => $selectedObject) {
if ($selectedObject == null) {
unset($this->selectedObjects[$complexId]);
}
}
if ($propertyName === 'complexId') {
$this->dispatch('client_form_complex_updated', complexId: $this->complexId);
}
try
{
try {
$this->validate();
$this->status = FormStatus::READY;
}
catch (\Exception $e)
{
} catch (\Exception $e) {
$this->status = FormStatus::IN_PROCESS;
}
}
#[On('plan7_selector_set_room')]
public function setPlan7Room($room) {
$this->plan7Room = $room;
public function setPlan7Room($data)
{
if ($data) {
$this->selectedObjects[$data['complexId']] = $data['room'];
}
}
public function render()
{
@ -212,47 +209,54 @@ public function back()
public function save()
{
if (
$hasErrors = false;
foreach ($this->selectedObjects as $complexId=>$room) {
if ($this->createDeal($complexId, $room)) {
unset($this->selectedObjects[$complexId]);
} else {
$hasErrors = true;
}
}
if ($hasErrors) {
return $this->status = FormStatus::ERROR;
}
$this->status = FormStatus::SUCCESS;
}
private function createDeal($complexId, $room)
{
if (
!$deal = Deal::create([
'agent_id' => $this->agentId,
'complex_id' => $this->complexId,
'plan7_data' => ($this->plan7Room) ? json_encode($this->plan7Room) : null
'agent_id' => $this->agentId,
'complex_id' => $complexId,
'plan7_data' => ($this->plan7Room) ? json_encode($room) : null
])
)
{
$this->status = FormStatus::ERROR;
return;
) {
return false;
}
foreach ($this->contacts as $contact)
{
foreach ($this->contacts as $contact) {
if (
!$newUser = Client::updateOrCreate(
['phone' => $contact['phones'][0]],
[
'name' => trim($contact['firstName'] . ' ' . $contact['secondName']),
'name' => trim($contact['firstName'] . ' ' . $contact['secondName']),
'phone' => $contact['phones'][0]
]
)
)
{
$this->status = FormStatus::ERROR;
return;
) {
return false;
}
if (
!$dealClient = DealClients::firstOrCreate([
'deal_id' => $deal->id,
'deal_id' => $deal->id,
'client_id' => $newUser->id
])
)
{
$this->status = FormStatus::ERROR;
return;
) {
return false;
}
}
$this->status = FormStatus::SUCCESS;
$this->dispatch('clientCreated');
return true;
}
}

View File

@ -144,22 +144,47 @@ class="bi bi-plus-circle" viewBox="0 0 16 16">
</div>
</div>
</div>
<div class="btn-group d-none">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
<div class="btn-group w-100">
<button class="btn btn-light d-flex justify-content-between rounded-4 p-3 align-items-center dropdown-toggle" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
Выберите жилой комплекс
</button>
<ul class="dropdown-menu">
@foreach ($complexes as $complex)
<li><div class="dropdown-item"><input class="form-check-input" type="checkbox" value="" id="checkDefault">
<label class="form-check-label" for="checkDefault">
{{ $complex['name'] }}
</label>
<li>
<div class="dropdown-item">
<input wire:model.live="selectedObjects.{{ $complex['id'] }}" class="form-check-input" type="checkbox" id="complex_selector_{{ $complex['id'] }}">
<label class="form-check-label" for="complex_selector_{{ $complex['id'] }}">
{{ $complex['name'] }}
</label>
</div>
</li>
@endforeach
</ul>
</div>
<div class="form-floating mb-2">
@if(count($selectedObjects))
<div class="d-flex flex-column gap-2 rounded-bottom-4 p-2" style="padding-top:25px!important;margin-top:-20px;background-color: #ffffff3b;">
@foreach($selectedObjects as $selectedComplexId=>$object)
@if(ComplexHasPlan7ApiData($selectedComplexId))
<div class="px-2 py-1 bg-light border border-1 rounded-4 bg-light">
<label for="complexId">Помещение в ЖК
@foreach ($complexes as $complex)
@if($complex['id'] == $selectedComplexId)
{{ $complex['name'] }}
@endif
@endforeach
</label>
<div>
@livewire('plan7Selector', [
'complexId' => $selectedComplexId
],
key($selectedComplexId))
</div>
</div>
@endif
@endforeach
</div>
@endif
<div class="d-none form-floating mb-2">
<select wire:model.live="complexId" class="form-select rounded-4 @error('complexId') is-invalid @enderror"
id="complexId" name="complexId" aria-label="Жилой комплекс">
<option selected></option>
@ -175,8 +200,8 @@ class="bi bi-plus-circle" viewBox="0 0 16 16">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
@if($complexId && ComplexHasPlan7ApiData($complexId))
<div class="p-2 bg-light border border-1 rounded-4 mb-3 bg-light">
<label for="complexId">Помещение</label>
@ -188,7 +213,7 @@ class="bi bi-plus-circle" viewBox="0 0 16 16">
</div>
@endif
@if (count($availableAgents) > 1)
<div class="form-floating mb-3">
<div class="mt-3 form-floating mb-3">
<select wire:model.live="agentId" class="form-select rounded-4 @error('agentId') is-invalid @enderror"
id="agentId" name="agent" aria-label="Агент">
<option selected></option>
@ -208,7 +233,7 @@ class="bi bi-plus-circle" viewBox="0 0 16 16">
@endif
@if ($status != FormStatus::READY)
<div class="">
<div class="d-none">
<button disabled class="btn btn-secondary disabled rounded-4 fw-bold fs-5 w-100 py-3"
style="background-color: #20184d;">
Создать нового клиента

View File

@ -80,11 +80,15 @@ public function setHouse($id)
public function setRoom($id)
{
$this->room = $this->allObjects['data'][$id];
$this->dispatch('plan7_selector_set_room', room: $this->room);
$data = [
'complexId' => $this->complexId,
'room' => $this->room
];
$this->dispatch('plan7_selector_set_room', data: $data);
}
public function unsetRoom() {
$this->room = false;
$this->dispatch('plan7_selector_set_room', room: false);
$this->dispatch('plan7_selector_set_room', data: false);
}
public function resetFilter() {
$this->filter = [];

View File

@ -17,7 +17,7 @@
@endif
<div>
<button type="button" class="btn btn-primary" wire:click="start()" wire:loading.class="opacity-50" wire:target="load" class="btn btn-primary"
onclick="plan7SelectorModal = new bootstrap.Modal(document.getElementById('plan7_selector_modal'), {});plan7SelectorModal.show()">
onclick="plan7SelectorModal = new bootstrap.Modal(document.getElementById('plan7_selector_modal_{{ $complexId }}'), {});plan7SelectorModal.show()">
@if($room)
Изменить
@else
@ -30,7 +30,7 @@
<!-- Modal -->
<div class="modal fade" wire:ignore.self id="plan7_selector_modal" tabindex="-1"
<div class="modal fade" wire:ignore.self id="plan7_selector_modal_{{ $complexId }}" tabindex="-1"
aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-xl modal-fullscreen-lg-down">
<div class="modal-content">

View File

@ -46,8 +46,8 @@ class="btn list-group-item list-group-item-action p-3 bg-white rounded border bo
</div>
</div>
</div>
<div class="col-12 col-lg-6">
<div class="p-2 px-sm-4 py-sm-3 bg-primary border rounded-3 mx-auto h-100" style="">
<div class="form-wrap col-12 col-lg-6">
<div class="form-wrap__inner p-2 px-sm-4 py-sm-3 bg-primary border rounded-3 mx-auto" style="">
<div class="h4 pb-2 mb-2 fw-bold d-flex flex-column">
<small>Добавить клиента</small>
</div>
@ -57,6 +57,24 @@ class="btn list-group-item list-group-item-action p-3 bg-white rounded border bo
</div>
@endif
</div>
<style>
.form-wrap {
position: relative;
min-height:450px;
max-height: 600px;
overflow: visible; /* чтобы нижняя часть могла выйти наружу */
}
.form-wrap__inner {
position: absolute;
top: 0;
left: 0;
right: 0;
min-height: 100%;
}
</style>
<div class="mt-3">
<div class="d-flex">
<div class="fs-5 fw-bold">Новости</div>