Добавил проверку данных через полимед и подтверждение через код верификации
This commit is contained in:
Binary file not shown.
@@ -6,6 +6,8 @@ from oauth2client.service_account import ServiceAccountCredentials
|
|||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
from config import config
|
from config import config
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
# Авторизация Google API
|
# Авторизация Google API
|
||||||
def authorize_google():
|
def authorize_google():
|
||||||
@@ -18,27 +20,172 @@ def authorize_google():
|
|||||||
client = gspread.authorize(creds)
|
client = gspread.authorize(creds)
|
||||||
return client
|
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'])
|
@webApp.route('/form_submit', methods=['POST'])
|
||||||
def form_submit():
|
def form_submit():
|
||||||
data = json.loads(request.data)
|
"""
|
||||||
# {'fio': '', 'tel': '', 'email': '', 'passport': '', 'passport_date': '', 'postal_code': '', 'address': '', 'snils': '', 'inn': '', 'dob': ''}
|
Обработка данных формы и обновление записи в Google Таблице.
|
||||||
data['current_time'] = datetime.datetime.now().strftime("%d.%m.%Y, %H:%M")
|
"""
|
||||||
|
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)})
|
||||||
|
|
||||||
|
|
||||||
sheet.append_row([
|
|
||||||
data['fio'],
|
|
||||||
data['tel'],
|
|
||||||
data['dob'],
|
|
||||||
data['user_id'], # Записываем Telegram ID пользователя
|
|
||||||
data['current_time'] # Записываем время отправки данных
|
|
||||||
])
|
|
||||||
|
|
||||||
return jsonify({'success':True})
|
|
||||||
|
@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"})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ошибка при обработке SMS верификации: {e}")
|
||||||
|
return jsonify({'success': False, "error": "Ошибка при обработке SMS верификации"})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@webApp.route('/')
|
@webApp.route('/')
|
||||||
|
|||||||
@@ -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")='Укажите ФИО пациента строго в формате “Фамилия Имя Отчество”. Если пациентом является Ваш ребенок, введите только ФИО ребенка.'
|
label.form-label.m-0(for="fio")='Укажите ФИО пациента строго в формате “Фамилия Имя Отчество”. Если пациентом является Ваш ребенок, введите только ФИО ребенка.'
|
||||||
input.form-control.tg_input#fio
|
input.form-control.tg_input#fio
|
||||||
small="(Пожалуйста, проверьте формат ввода)"
|
small="(Пожалуйста, проверьте формат ввода)"
|
||||||
.my-3.mx-4.success-field
|
.my-3.mx-4.success-field.primary-field
|
||||||
label.form-label.m-0(for="tel")="Телефон"
|
label.form-label.m-0(for="tel")="Телефон"
|
||||||
.row.m-0.p-0.justify-content-between
|
.row.m-0.p-0.justify-content-between
|
||||||
.col-auto.m-0.p-0(style="min-width: 85%;")
|
.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
|
button.btn.btn-danger#clear_tel
|
||||||
span.x-icn
|
span.x-icn
|
||||||
small="(Пожалуйста, проверьте формат ввода)"
|
small="(Пожалуйста, проверьте формат ввода)"
|
||||||
.my-3.mx-4.success-field
|
.my-3.mx-4.success-field.primary-field
|
||||||
label.form-label.m-0(for="dob")='Укажите год рождения пациента в формате YYYY. Если пациентом является Ваш ребенок, введите только год рождения ребенка в формате YYYY.'
|
label.form-label.m-0(for="dob")='Укажите год рождения пациента в формате YYYY. Если пациентом является Ваш ребенок, введите только год рождения ребенка в формате YYYY.'
|
||||||
input.form-control.tg_input#dob
|
input.form-control.tg_input#dob(type="date")
|
||||||
small="(Пожалуйста, проверьте формат ввода)"
|
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")='Код верификации'
|
label.form-label.m-0(for="kod")='Код верификации'
|
||||||
input.form-control#kod
|
input.form-control#kod
|
||||||
small="(Пожалуйста, проверьте формат ввода)"
|
small="(Пожалуйста, проверьте формат ввода)"
|
||||||
|
|
||||||
.my-3.mx-4
|
.my-3.mx-4.primary-field
|
||||||
button.btn.btn-success.float-end.mb-3#form_submit
|
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.spinner-border.spinner-border-sm.me-1.d-none(role="status" aria-hidden="true")
|
||||||
span="Подтвердить"
|
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="Отправить код"
|
||||||
@@ -64,22 +64,20 @@ $(document).ready(function(){
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
$("#dob").attr('maxlength','4');
|
// Проверка на дату рождения (не старше 80 лет)
|
||||||
$('#dob').on('input', function() {
|
$('#dob').on('change', function() {
|
||||||
let input = $(this).val();
|
const dob = new Date($(this).val());
|
||||||
// Удаляем все символы, кроме цифр
|
const currentDate = new Date();
|
||||||
input = input.replace(/\D/g, '');
|
const age = currentDate.getFullYear() - dob.getFullYear();
|
||||||
// Обновляем поле ввода
|
|
||||||
$(this).val(input);
|
|
||||||
|
|
||||||
// Проверка на минимальную длину (не менее 11 символов)
|
// Проверка на возраст (не старше 80 лет)
|
||||||
if (input.length < 4) {
|
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');
|
$(this).parent().removeClass('success-field').addClass('errors-field');
|
||||||
} else {
|
} else {
|
||||||
// Если введено достаточно цифр, показываем успех
|
// Если возраст нормален, подсвечиваем ячейку как успешную
|
||||||
$(this).parent().removeClass('errors-field').addClass('success-field');
|
$(this).parent().removeClass('errors-field').addClass('success-field');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -108,6 +106,7 @@ $(document).ready(function(){
|
|||||||
message = {}
|
message = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(!(validate_length($('#fio').val(), 3)))
|
if(!(validate_length($('#fio').val(), 3)))
|
||||||
{
|
{
|
||||||
show_error('Введите ФИО', false);
|
show_error('Введите ФИО', false);
|
||||||
@@ -124,20 +123,94 @@ $(document).ready(function(){
|
|||||||
return;
|
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);
|
show_error('Дата рождения должна быть корректной и возраст не более 80 лет', false);
|
||||||
$(this).children(".spinner-border").addClass('d-none');
|
$(this).children(".spinner-border").addClass('d-none');
|
||||||
$(this).removeAttr("disabled");
|
$(this).removeAttr("disabled");
|
||||||
return;
|
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) {
|
$.each($('.tg_input'), function(e) {
|
||||||
message[$(this).prop("id")] = $(this).val();
|
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({
|
$.ajax({
|
||||||
type: "post",
|
type: "post",
|
||||||
url: "/form_submit",
|
url: "/form_submit",
|
||||||
@@ -147,10 +220,8 @@ $(document).ready(function(){
|
|||||||
data: JSON.stringify(message),
|
data: JSON.stringify(message),
|
||||||
success: (data) => {
|
success: (data) => {
|
||||||
if(data.success==true){
|
if(data.success==true){
|
||||||
$(this).children(".spinner-border").addClass('d-none');
|
$('.primary-field').hide();
|
||||||
$(this).removeAttr("disabled");
|
$('.verification').show();
|
||||||
console.log(data);
|
|
||||||
show_success("Данные сохранены!")
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
show_error(data.error);
|
show_error(data.error);
|
||||||
|
|||||||
Reference in New Issue
Block a user