feat: добавлена функциональность политики конфиденциальности и согласия на обработку ПД

Основные изменения:

Backend:
- Добавлена миграция для поля privacy_consented_at в таблицу telecart_customers
- Создан PrivacyPolicyHandler с методами:
  * checkIsUserPrivacyConsented - проверка наличия согласия пользователя
  * userPrivacyConsent - сохранение согласия пользователя
- Обновлен TelegramService для извлечения userId из initData
- Обновлен TelegramServiceProvider для внедрения зависимостей
- Добавлены новые маршруты в routes.php
- Обновлен SettingsHandler для возврата privacy_policy_link
- Обновлен TelegramCustomersHandler для включения privacy_consented_at в ответы
- Обновлены тесты TelegramServiceTest

Frontend (SPA):
- Создан компонент PrivacyPolicy.vue для отображения запроса согласия
- Добавлена проверка согласия при инициализации приложения (main.js)
- Обновлен App.vue для отображения компонента PrivacyPolicy
- Добавлены функции checkIsUserPrivacyConsented и userPrivacyConsent в ftch.js
- Обновлен SettingsStore для хранения privacy_policy_link и is_privacy_consented

Frontend (Admin):
- Добавлено поле privacy_policy_link в настройки (settings.js)
- Добавлена настройка ссылки на политику конфиденциальности в GeneralView.vue
- Обновлен CustomersView.vue:
  * Добавлена колонка privacy_consented_at с отображением даты согласия
  * Добавлена поддержка help-текста для колонок с иконкой вопроса и tooltip
  * Добавлены help-тексты для колонок last_seen_at, privacy_consented_at, created_at
  * Улучшено форматирование кода
This commit is contained in:
2025-11-23 23:17:21 +03:00
committed by Nikita Kiselev
parent 9a93cc7342
commit 7a5eebec91
16 changed files with 378 additions and 52 deletions

View File

@@ -0,0 +1,42 @@
<template>
<div v-if="isShown" class="toast toast-center bottom-20 z-50">
<div class="alert alert-info">
<span>
Используя магазин, вы соглашаетесь с
<a v-if="settings.privacy_policy_link"
href="#" class="underline"
@click.prevent="showPrivacyPolicy"
>обработкой персональных данных</a>
<span v-else>обработкой персональных данных</span>.
</span>
<button
class="btn btn-outline"
@click="privacyConsent"
>
OK
</button>
</div>
</div>
</template>
<script setup>
import {userPrivacyConsent} from "@/utils/ftch.js";
import {ref} from "vue";
import {useSettingsStore} from "@/stores/SettingsStore.js";
const isShown = ref(true);
const settings = useSettingsStore();
async function privacyConsent() {
isShown.value = false;
await userPrivacyConsent();
}
function showPrivacyPolicy() {
if (settings.privacy_policy_link) {
window.Telegram.WebApp.openLink(settings.privacy_policy_link, {
try_instant_view: true,
});
}
}
</script>