diff --git a/webApp/interfaces/__pycache__/pagesController.cpython-38.pyc b/webApp/interfaces/__pycache__/pagesController.cpython-38.pyc index dd4896b..8143ca6 100644 Binary files a/webApp/interfaces/__pycache__/pagesController.cpython-38.pyc and b/webApp/interfaces/__pycache__/pagesController.cpython-38.pyc differ diff --git a/webApp/interfaces/pagesController.py b/webApp/interfaces/pagesController.py index 4198a82..dc7e58b 100644 --- a/webApp/interfaces/pagesController.py +++ b/webApp/interfaces/pagesController.py @@ -6,6 +6,8 @@ from oauth2client.service_account import ServiceAccountCredentials import json import datetime from config import config +import requests + # Авторизация Google API def authorize_google(): @@ -18,27 +20,172 @@ def authorize_google(): client = gspread.authorize(creds) return client +def find_patients(data): + """ + Поиск пациента в таблице по данным. + """ + sheet = authorize_google().open("Пациенты клиники").sheet1 + records = sheet.get_all_records() # Получаем все строки таблицы + + for i, record in enumerate(records, start=2): # Нумерация строк Google Таблицы начинается с 2 + try: + if ( + str(record.get("Telegram ID", "")).strip() == str(data.get("user_id", "")).strip() and + str(record.get("ФИО", "")).strip().lower() == str(data.get("fio", "")).strip().lower() and + str(record.get("Дата рождения", "")).strip() == str(data.get("dob", "")).strip() and + str(record.get("Номер телефона", "")).strip() == str(data.get("tel", "")).strip() + ): + return i, record # Возвращаем номер строки и запись + except Exception as e: + print(f"Ошибка при сравнении записи: {e}") + continue + + return None, None + -# Обработка формы @webApp.route('/form_submit', methods=['POST']) def form_submit(): - data = json.loads(request.data) - # {'fio': '', 'tel': '', 'email': '', 'passport': '', 'passport_date': '', 'postal_code': '', 'address': '', 'snils': '', 'inn': '', 'dob': ''} - data['current_time'] = datetime.datetime.now().strftime("%d.%m.%Y, %H:%M") + """ + Обработка данных формы и обновление записи в Google Таблице. + """ + try: + data = json.loads(request.data) + data['current_time'] = datetime.datetime.now().strftime("%d.%m.%Y, %H:%M") - # Авторизация и добавление данных в Google Sheets - sheet = authorize_google().open("Пациенты клиники").sheet1 + # Поиск пациента + row_number, patient_row = find_patients(data) + if not patient_row: + return jsonify({'success': False, 'error': "Пациент не найден"}) + + # Проверка кода верификации + expected_code = str(patient_row.get("Верификация", "")).strip() + received_code = str(data.get("verification_code", "")).strip() + if expected_code != received_code: + return jsonify({'success': False, 'error': "Код верификации не совпадает"}) + + # Обновление записи в таблице + sheet = authorize_google().open("Пациенты клиники").sheet1 + + # Определяем динамический столбец по заголовкам + headers = sheet.row_values(1) + verification_col = headers.index("Верификация") + 1 # Столбцы нумеруются с 1 + sheet.update_cell(row_number, verification_col, "Пройдена") + + return jsonify({'success': True}) + + except KeyError as e: + print(f"Ключ отсутствует в данных: {e}") + return jsonify({'success': False, 'error': f"Некорректные данные: {e}"}) + + except Exception as e: + print(f"Ошибка при обработке формы: {e}") + return jsonify({'success': False, 'error': str(e)}) + + + + +@webApp.route('/tel_verification', methods=['POST']) +def send_registration_request(): + raw_data = json.loads(request.data) + print("Полученные данные:", raw_data) + """ + Блок записи в Полимед + """ + try: + HEADER = { + "Content-Type": "application/json" + } + + # Разделение ФИО на части + fio = raw_data.get("fio", "") + parts = fio.split(" ") + if len(parts) < 3: + return jsonify({'success': False, "error": "ФИО должно содержать 3 слова"}) + + first_name = parts[1] + middle_name = " ".join(parts[2:]) + last_name = parts[0] + + # Обработка номера телефона + raw_phone = raw_data.get("tel", "") + formatted_phone = ''.join(filter(str.isdigit, raw_phone)) + if formatted_phone.startswith("7"): + formatted_phone = formatted_phone + + # Обработка даты рождения + dob = raw_data.get("dob", "") + if not dob: + return jsonify({'success': False, "error": "Дата рождения отсутствует"}) + birth_year = dob.split("-")[0] # Предполагается формат "YYYY-MM-DD" + + # Данные для отправки в сервер Полимед + data = { + "telegram_id": raw_data.get("user_id"), + "first_name": first_name, + "second_name": middle_name, + "last_name": last_name, + "mobile_phone": formatted_phone, + "birthday": birth_year + } + + print("Отправляемые данные на сервер:", data) + response = requests.post("http://46.146.229.242:1980/AppFindPac", headers=HEADER, json=data) + + if response.status_code == 200: + result = response.json() + print("Результат JSON:", result) + if result.get('ok'): + return jsonify({'success': False, "error": "Пользователь уже существует"}) + else: + print(f"Ошибка при отправке данных. Статус-код: {response.status_code}") + return jsonify({'success': False, "error": "Ошибка отправки данных в Полимед"}) + + except Exception as e: + print(f"Ошибка обработки данных для Полимед: {e}") + return jsonify({'success': False, "error": "Ошибка обработки данных для Полимед"}) + + """ + Блок верификации через SMS + """ + try: + url = "https://sms.ru/code/call" + api_key = "2ED72E61-76C8-5637-3587-2792D47B698C" + + # Отправка запроса на вызов с кодом верификации + response = requests.post(url, data={"phone": formatted_phone, "api_id": api_key}) + json_data = response.json() + + verification_code = None + current_time = datetime.datetime.now().strftime("%d.%m.%Y, %H:%M") + + # Авторизация и доступ к таблице + sheet = authorize_google().open("Пациенты клиники").sheet1 + + # Проверка успешного получения кода + if json_data and json_data["status"] == "OK": + verification_code = json_data.get("code") + + # Записываем данные и код верификации в таблицу + sheet.append_row([ + fio, + raw_phone, + dob, + raw_data.get("user_id"), # Telegram ID пользователя + current_time, # Время отправки данных + verification_code # Код верификации + ]) + print(f"Код верификации, отправленный пользователю: {verification_code}") + return jsonify({'success': True}) + else: + print("Звонок не может быть выполнен.") + print("Текст ошибки:", json_data.get("status_text")) + return jsonify({'success': False, "error": "Ошибка вызова через SMS.ru"}) - sheet.append_row([ - data['fio'], - data['tel'], - data['dob'], - data['user_id'], # Записываем Telegram ID пользователя - data['current_time'] # Записываем время отправки данных - ]) + except Exception as e: + print(f"Ошибка при обработке SMS верификации: {e}") + return jsonify({'success': False, "error": "Ошибка при обработке SMS верификации"}) - return jsonify({'success':True}) @webApp.route('/') diff --git a/webApp/templates/2.0/main_page.pug b/webApp/templates/2.0/main_page.pug index ba849f9..9dc6925 100644 --- a/webApp/templates/2.0/main_page.pug +++ b/webApp/templates/2.0/main_page.pug @@ -22,11 +22,11 @@ script(type="text/javascript", src="/js/2.0.dashboard.js?q="~randomString()) - .my-3.mx-4.success-field + .my-3.mx-4.success-field.primary-field label.form-label.m-0(for="fio")='Укажите ФИО пациента строго в формате “Фамилия Имя Отчество”. Если пациентом является Ваш ребенок, введите только ФИО ребенка.' input.form-control.tg_input#fio small="(Пожалуйста, проверьте формат ввода)" - .my-3.mx-4.success-field + .my-3.mx-4.success-field.primary-field label.form-label.m-0(for="tel")="Телефон" .row.m-0.p-0.justify-content-between .col-auto.m-0.p-0(style="min-width: 85%;") @@ -35,17 +35,22 @@ script(type="text/javascript", src="/js/2.0.dashboard.js?q="~randomString()) button.btn.btn-danger#clear_tel span.x-icn small="(Пожалуйста, проверьте формат ввода)" - .my-3.mx-4.success-field + .my-3.mx-4.success-field.primary-field label.form-label.m-0(for="dob")='Укажите год рождения пациента в формате YYYY. Если пациентом является Ваш ребенок, введите только год рождения ребенка в формате YYYY.' - input.form-control.tg_input#dob + input.form-control.tg_input#dob(type="date") small="(Пожалуйста, проверьте формат ввода)" - //.my-3.mx-4.success-field#verification(style="display: none;") + .my-3.mx-4.success-field.verification(style="display: none;") label.form-label.m-0(for="kod")='Код верификации' input.form-control#kod small="(Пожалуйста, проверьте формат ввода)" - .my-3.mx-4 + .my-3.mx-4.primary-field button.btn.btn-success.float-end.mb-3#form_submit span.spinner-border.spinner-border-sm.me-1.d-none(role="status" aria-hidden="true") - span="Подтвердить" \ No newline at end of file + span="Подтвердить" + + .my-3.mx-4.primary-field.verification(style="display: none;") + button.btn.btn-success.float-end.mb-3#code_submit + span.spinner-border.spinner-border-sm.me-1.d-none(role="status" aria-hidden="true") + span="Отправить код" \ No newline at end of file diff --git a/webApp/templates/static/js/2.0.dashboard.js b/webApp/templates/static/js/2.0.dashboard.js index 58c429c..0b70c26 100644 --- a/webApp/templates/static/js/2.0.dashboard.js +++ b/webApp/templates/static/js/2.0.dashboard.js @@ -64,22 +64,20 @@ $(document).ready(function(){ - $("#dob").attr('maxlength','4'); - $('#dob').on('input', function() { - let input = $(this).val(); - // Удаляем все символы, кроме цифр - input = input.replace(/\D/g, ''); - // Обновляем поле ввода - $(this).val(input); - - // Проверка на минимальную длину (не менее 11 символов) - if (input.length < 4) { - // Если введено меньше цифр, показываем ошибку - $(this).parent().removeClass('success-field').addClass('errors-field'); - } else { - // Если введено достаточно цифр, показываем успех - $(this).parent().removeClass('errors-field').addClass('success-field'); - } + // Проверка на дату рождения (не старше 80 лет) + $('#dob').on('change', function() { + const dob = new Date($(this).val()); + const currentDate = new Date(); + const age = currentDate.getFullYear() - dob.getFullYear(); + + // Проверка на возраст (не старше 80 лет) + if (age > 100 || (age === 100 && (currentDate.getMonth() < dob.getMonth() || (currentDate.getMonth() === dob.getMonth() && currentDate.getDate() < dob.getDate())))) { + // Если возраст больше 80 лет, подсвечиваем ячейку как ошибку + $(this).parent().removeClass('success-field').addClass('errors-field'); + } else { + // Если возраст нормален, подсвечиваем ячейку как успешную + $(this).parent().removeClass('errors-field').addClass('success-field'); + } }); @@ -108,6 +106,7 @@ $(document).ready(function(){ message = {} + if(!(validate_length($('#fio').val(), 3))) { show_error('Введите ФИО', false); @@ -124,20 +123,94 @@ $(document).ready(function(){ return; } - if ($('#dob').val().length !== 4 || new Date().getFullYear() - new Date($('#dob').val()).getFullYear() > 80) { + if ($('#dob').val().length !== 10 || new Date().getFullYear() - new Date($('#dob').val()).getFullYear() > 100) { show_error('Дата рождения должна быть корректной и возраст не более 80 лет', false); $(this).children(".spinner-border").addClass('d-none'); $(this).removeAttr("disabled"); return; } + if ($('#dob').val().length !== 10 || new Date().getFullYear() < new Date($('#dob').val()).getFullYear()) { + show_error('Проверьте дату ввода, вы указали дату больше чем сегодняшняя дата', false); + $(this).children(".spinner-border").addClass('d-none'); + $(this).removeAttr("disabled"); + return; + } + + $.each($('.tg_input'), function(e) { + message[$(this).prop("id")] = $(this).val(); + }); + + $.ajax({ + type: "post", + url: "/tel_verification", + processData: false, // tell jQuery not to process the data + contentType: false, // tell jQuery not to set contentType + async: true, + data: JSON.stringify(message), + success: (data) => { + if(data.success==true){ + $('.primary-field').hide(); + $('.verification').show(); + } + else{ + show_error(data.error); + $(this).children(".spinner-border").addClass('d-none'); + $(this).removeAttr("disabled"); + } + }, + error:function (jqXHR, exception) { + $(this).children(".spinner-border").addClass('d-none'); + $(this).removeAttr("disabled"); + show_error('Что-то пошло не так', false) + } + }); + }); + + $("#code_submit").click(function(){ + + $(this).children(".spinner-border").removeClass('d-none'); + $(this).attr("disabled", true); + message = {} + + + + if(!(validate_length($('#fio').val(), 3))) + { + show_error('Введите ФИО', false); + $(this).children(".spinner-border").addClass('d-none'); + $(this).removeAttr("disabled"); + return; + } + if(!(validate_length($('#tel').val(), 16))) + { + show_error('Введите Телефон', false); + $(this).children(".spinner-border").addClass('d-none'); + $(this).removeAttr("disabled"); + return; + } + if ($('#dob').val().length !== 10 || new Date().getFullYear() - new Date($('#dob').val()).getFullYear() > 100) { + show_error('Дата рождения должна быть корректной и возраст не более 80 лет', false); + $(this).children(".spinner-border").addClass('d-none'); + $(this).removeAttr("disabled"); + return; + } + if ($('#dob').val().length !== 10 || new Date().getFullYear() < new Date($('#dob').val()).getFullYear()) { + show_error('Проверьте дату ввода, вы указали дату больше чем сегодняшняя дата', false); + $(this).children(".spinner-border").addClass('d-none'); + $(this).removeAttr("disabled"); + return; + } $.each($('.tg_input'), function(e) { message[$(this).prop("id")] = $(this).val(); }); + + message["verification_code"] = $("#kod").val(); + $.ajax({ type: "post", url: "/form_submit", @@ -147,10 +220,8 @@ $(document).ready(function(){ data: JSON.stringify(message), success: (data) => { if(data.success==true){ - $(this).children(".spinner-border").addClass('d-none'); - $(this).removeAttr("disabled"); - console.log(data); - show_success("Данные сохранены!") + $('.primary-field').hide(); + $('.verification').show(); } else{ show_error(data.error);