From e4e00184a59d70c497e9169094eca50744c96643 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 8 Jun 2025 19:46:23 +0300 Subject: [PATCH] change services api --- .../kfu-m-24-1/sber_mobile/DB_Scheme.txt | 47 ++++++++------ .../sber_mobile/utility_payments.js | 61 +++++++++++++++---- 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/server/routers/kfu-m-24-1/sber_mobile/DB_Scheme.txt b/server/routers/kfu-m-24-1/sber_mobile/DB_Scheme.txt index 81dade2..ef5844a 100644 --- a/server/routers/kfu-m-24-1/sber_mobile/DB_Scheme.txt +++ b/server/routers/kfu-m-24-1/sber_mobile/DB_Scheme.txt @@ -77,16 +77,6 @@ CREATE TABLE building_management_services ( PRIMARY KEY (building_id, service_id) ); --- 8. Платежные сервисы -CREATE TABLE payment_services ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - name TEXT NOT NULL, - logo_url TEXT, - provider_name TEXT, - created_at TIMESTAMPTZ DEFAULT NOW(), - updated_at TIMESTAMPTZ DEFAULT NOW() -); - -- 9. Дополнительные сервисы CREATE TABLE additional_services ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), @@ -153,19 +143,40 @@ CREATE TABLE cameras ( updated_at TIMESTAMPTZ DEFAULT NOW() ); --- 15. Платежи ЖКХ (исправленная версия) -CREATE TABLE utility_payments ( +-- 15. Агрегаторы платежных сервисов (ЖКХ, Интернет и т.д.) +CREATE TABLE payment_services ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - apartment_id UUID NOT NULL REFERENCES apartments(id), - service_id UUID NOT NULL REFERENCES payment_services(id), - amount DECIMAL(10, 2) NOT NULL, - period DATE NOT NULL, - status TEXT NOT NULL CHECK (status IN ('paid', 'pending', 'overdue')), + name TEXT NOT NULL, -- Например, "ЖКХ", "Интернет" + icon TEXT, -- Можно хранить название иконки или url created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); --- 16. Заявки +-- 16. Детализация услуг внутри агрегатора (отопление, вода и т.д.) +CREATE TABLE payment_service_details ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + service_id UUID NOT NULL REFERENCES payment_services(id), + name TEXT NOT NULL, -- Например, "Отопление" + description TEXT, -- Описание услуги + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- 17. Платежи пользователя по деталям услуг +CREATE TABLE payments ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES auth.users(id), + apartment_id UUID REFERENCES apartments(id), + detail_id UUID NOT NULL REFERENCES payment_service_details(id), + amount DECIMAL(10, 2) NOT NULL, + period DATE NOT NULL, + status TEXT NOT NULL CHECK (status IN ('paid', 'pending', 'overdue')), + payment_method TEXT CHECK (payment_method IN ('card', 'sber')), + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- 18. Заявки CREATE TABLE tickets ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES auth.users(id), diff --git a/server/routers/kfu-m-24-1/sber_mobile/utility_payments.js b/server/routers/kfu-m-24-1/sber_mobile/utility_payments.js index a6e8b98..2675059 100644 --- a/server/routers/kfu-m-24-1/sber_mobile/utility_payments.js +++ b/server/routers/kfu-m-24-1/sber_mobile/utility_payments.js @@ -1,17 +1,56 @@ const router = require('express').Router(); const { getSupabaseClient } = require('./supabaseClient'); -// Получить все платежи по конкретной квартире с данными сервиса -router.get('/utility-payments', async (req, res) => { +// Получить агрегированные сервисы с деталями и статусами оплаты для квартиры +router.get('/payment-services', async (req, res) => { const supabase = getSupabaseClient(); - const { apartment_id } = req.query; - if (!apartment_id) return res.status(400).json({ error: 'apartment_id required' }); - const { data, error } = await supabase - .from('utility_payments') - .select('*, payment_services(*)') - .eq('apartment_id', apartment_id); - if (error) return res.status(400).json({ error: error.message }); - res.json(data); + const { apartment_id, user_id } = req.query; + if (!apartment_id || !user_id) return res.status(400).json({ error: 'apartment_id и user_id обязательны' }); + + // Получаем все агрегаторы + const { data: services, error: servicesError } = await supabase + .from('payment_services') + .select('id, name, icon'); + if (servicesError) return res.status(400).json({ error: servicesError.message }); + + // Получаем детали по агрегаторам + const { data: details, error: detailsError } = await supabase + .from('payment_service_details') + .select('id, service_id, name, description'); + if (detailsError) return res.status(400).json({ error: detailsError.message }); + + // Получаем платежи пользователя по деталям + const { data: payments, error: paymentsError } = await supabase + .from('payments') + .select('id, detail_id, amount, period, status, payment_method') + .eq('apartment_id', apartment_id) + .eq('user_id', user_id); + if (paymentsError) return res.status(400).json({ error: paymentsError.message }); + + // Формируем структуру для фронта + const result = services.map(service => { + const serviceDetails = details.filter(d => d.service_id === service.id).map(detail => { + const payment = payments.find(p => p.detail_id === detail.id) || {}; + return { + id: detail.id, + name: detail.name, + description: detail.description, + amount: payment.amount || null, + period: payment.period || null, + status: payment.status || 'pending', + paymentMethod: payment.payment_method || null, + paymentId: payment.id || null, + }; + }); + return { + id: service.id, + name: service.name, + icon: service.icon, + details: serviceDetails, + }; + }); + + res.json(result); }); -module.exports = router; \ No newline at end of file +module.exports = router; \ No newline at end of file