Compare commits

...

5 Commits

6 changed files with 47 additions and 297 deletions
Generated
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
+2 -2
View File
@@ -1,6 +1,6 @@
[WEB_APP] [WEB_APP]
PORT = 8084 PORT = 8083
template_folder = C:\Users\ilyac\PycharmProjects\tgFlaskForm\webApp\templates template_folder = C:\Users\ilyac\PycharmProjects\tgFlaskFormPolimed\webApp\templates
environment = test environment = test
[GOOGLE] [GOOGLE]
type = service_account type = service_account
+1 -26
View File
@@ -18,17 +18,6 @@ def authorize_google():
client = gspread.authorize(creds) client = gspread.authorize(creds)
return client return client
# Функция проверки существования пользователя в таблице
def user_exists(sheet, fio, tel, user_id):
records = sheet.get_all_values() # Получаем все данные таблицы без заголовков
for row in records[1:]: # Пропускаем первую строку, если там заголовки, или уберите [1:], если заголовков нет
if len(row) > 1 and row[0] == fio and row[1] == tel:# and row[13] == user_id:
return True, 'Ваши данные уже присутствуют в таблице' # Если ФИО, телефон и user_id совпадают, значит, запись уже существует
if row[13] == user_id:
return True, 'C данного Telegram аккаунта уже проведена регистрация'
return False, 'Ок'
# Обработка формы # Обработка формы
@webApp.route('/form_submit', methods=['POST']) @webApp.route('/form_submit', methods=['POST'])
@@ -38,26 +27,12 @@ def form_submit():
data['current_time'] = datetime.datetime.now().strftime("%d.%m.%Y, %H:%M") data['current_time'] = datetime.datetime.now().strftime("%d.%m.%Y, %H:%M")
# Авторизация и добавление данных в Google Sheets # Авторизация и добавление данных в Google Sheets
sheet = authorize_google().open("Информация о сотрудниках").sheet1 sheet = authorize_google().open("Пациенты клиники").sheet1
# Проверка, существует ли уже пользователь
exists_flag, message = user_exists(sheet, data['fio'], data['tel'], data['user_id'])
if exists_flag:
return jsonify({'success': False, 'error': message})
sheet.append_row([ sheet.append_row([
data['fio'], data['fio'],
data['tel'], data['tel'],
data['email'],
data['passport'][:5],
data['passport'][5:],
data['passport_issued_by'],
data['passport_date'],
data['postal_code'],
data['address'],
data['residential_address'],
data['snils'],
data['inn'],
data['dob'], data['dob'],
data['user_id'], # Записываем Telegram ID пользователя data['user_id'], # Записываем Telegram ID пользователя
data['current_time'] # Записываем время отправки данных data['current_time'] # Записываем время отправки данных
+9 -37
View File
@@ -22,9 +22,10 @@ script(type="text/javascript", src="/js/2.0.dashboard.js?q="~randomString())
.my-3.mx-4 .my-3.mx-4.success-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="(Пожалуйста, проверьте формат ввода)"
.my-3.mx-4.success-field .my-3.mx-4.success-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
@@ -35,42 +36,13 @@ script(type="text/javascript", src="/js/2.0.dashboard.js?q="~randomString())
span.x-icn span.x-icn
small="(Пожалуйста, проверьте формат ввода)" small="(Пожалуйста, проверьте формат ввода)"
.my-3.mx-4.success-field .my-3.mx-4.success-field
label.form-label.m-0(for="dob")='Дата рождения' label.form-label.m-0(for="dob")='Укажите год рождения пациента в формате YYYY. Если пациентом является Ваш ребенок, введите только год рождения ребенка в формате YYYY.'
input.form-control.tg_input#dob(type="date") input.form-control.tg_input#dob
small="(Пожалуйста, проверьте формат ввода)" small="(Пожалуйста, проверьте формат ввода)"
.my-3.mx-4.success-field
label.form-label.m-0(for="email")='Электронная почта' //.my-3.mx-4.success-field#verification(style="display: none;")
input.form-control.tg_input#email label.form-label.m-0(for="kod")='Код верификации'
small="(Пожалуйста, проверьте формат ввода)" input.form-control#kod
.my-3.mx-4.success-field
label.form-label.m-0(for="passport")='Серия и номер паспорта'
input.form-control.tg_input#passport
small="(Пожалуйста, проверьте формат ввода)"
.my-3.mx-4.success-field
label.form-label.m-0(for="passport_date")='Дата выдачи паспорта'
input.form-control.tg_input#passport_date(type="date")
small="(Пожалуйста, проверьте формат ввода)"
.my-3.mx-4.success-field
label.form-label.m-0(for="postal_code")='Код подразделения'
input.form-control.tg_input#postal_code
small="(Пожалуйста, проверьте формат ввода)"
.my-3.mx-4
label.form-label.m-0(for="passport_issued_by")='Кем выдан паспорт'
select.form-select.tg_input#passport_issued_by(style="")
option(disabled, selected)="Кем выдан паспорт"
.my-3.mx-4
label.form-label.m-0(for="address")='Адрес регистрации'
input.form-control.tg_input#address
.my-3.mx-4
label.form-label.m-0(for="residential_address")='Адрес проживания'
input.form-control.tg_input#residential_address
.my-3.mx-4.success-field
label.form-label.m-0(for="snils")='СНИЛС'
input.form-control.tg_input#snils
small="(Пожалуйста, проверьте формат ввода)"
.my-3.mx-4.success-field
label.form-label.m-0(for="inn")='ИНН'
input.form-control.tg_input#inn
small="(Пожалуйста, проверьте формат ввода)" small="(Пожалуйста, проверьте формат ввода)"
.my-3.mx-4 .my-3.mx-4
+28 -232
View File
@@ -22,50 +22,37 @@ function validate_length(val, dest_len){
$(document).ready(function(){ $(document).ready(function(){
const validateEmail = (email) => {
return email.match(
/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
);
};
const validate = () => {
const email = $('#email').val();
if(validateEmail(email)){
$('#email').parent().removeClass('errors-field').addClass('success-field');
} else{
$('#email').parent().removeClass('success-field').addClass('errors-field');
}
return false;
}
$('#email').on('input', validate);
$('body').append('<div id="error_alert" class="alert alert-danger" role="alert" style="position: fixed; top: 50px; left: 10%; right: 10%; z-index: 9999; display: none;">Ошибка<br><small id="alert_error_text"></small></div>'); $('body').append('<div id="error_alert" class="alert alert-danger" role="alert" style="position: fixed; top: 50px; left: 10%; right: 10%; z-index: 9999; display: none;">Ошибка<br><small id="alert_error_text"></small></div>');
$('body').append('<div id="success_alert" class="alert alert-success" role="alert" style="position: fixed; top: 50px; left: 10%; right: 10%; z-index: 9999; display: none;">Успех<br><small id="alert_success_text"></small></div>'); $('body').append('<div id="success_alert" class="alert alert-success" role="alert" style="position: fixed; top: 50px; left: 10%; right: 10%; z-index: 9999; display: none;">Успех<br><small id="alert_success_text"></small></div>');
$('#fio').on('input', function() {
$('#fio').on('input', function () {
let input = $(this).val(); let input = $(this).val();
// Убираем все лишние символы, кроме букв и пробелов
input = input.replace(/[^a-zA-Zа-яА-ЯёЁ ]/g, ''); input = input.replace(/[^a-zA-Zа-яА-ЯёЁ ]/g, '');
// Разделение текста по пробелам и преобразование каждого слова
let words = input.split(/\s+/); // Разбиваем по пробелам // Преобразуем каждое слово, чтобы оно начиналось с заглавной буквы
// Преобразуем каждое слово let formattedInput = input.split(' ').map(word => {
let formattedInput = words.map(word => {
if (word.length > 0) { if (word.length > 0) {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
} }
return ''; // Если слово пустое (например, несколько пробелов), не изменяем return ''; // Пустые слова не трогаем
}).join(' '); // Объединяем обратно с пробелами }).join(' '); // Объединяем обратно с пробелами
// Обновляем поле ввода с отформатированным текстом // Обновляем поле ввода с отформатированным текстом
$(this).val(formattedInput); $(this).val(formattedInput);
// Проверяем количество слов
let words = formattedInput.trim().split(/\s+/); // Убираем лишние пробелы
if (words.length < 3 || words.some(word => word.length < 2)) {
$(this).parent().removeClass('success-field').addClass('errors-field'); // Подсветить поле
} else {
$(this).parent().removeClass('errors-field').addClass('success-field'); // Убрать подсветку
}
}); });
$('#email').on('input', function() {
let input = $(this).val();
// Разрешаем только буквы, цифры, точки, дефисы и подчеркивания
input = input.replace(/[^a-zA-Z0-9._@-]/g, '');
// Обновляем поле ввода
$(this).val(input);
});
$('#tel').on('change', function() { $('#tel').on('change', function() {
if($(this).val().length != 16){ if($(this).val().length != 16){
@@ -75,70 +62,18 @@ $(document).ready(function(){
} }
}); });
// Проверка на дату рождения (не старше 80 лет)
$('#dob').on('change', function() {
const dob = new Date($(this).val());
const currentDate = new Date();
const age = currentDate.getFullYear() - dob.getFullYear();
// Проверка на возраст (не старше 80 лет)
if (age > 80 || (age === 80 && (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');
}
});
// Проверка на дату выдачи паспорта (выдан после 14, 20 или 45 лет) $("#dob").attr('maxlength','4');
$('#passport_date').on('change', function() { $('#dob').on('input', function() {
const passportDate = new Date($(this).val());
const dob = new Date($('#dob').val());
// Проверка, что дата рождения введена и корректна
if (!dob || isNaN(dob)) {
// Если дата рождения не введена или неверна, показываем ошибку
$(this).parent().removeClass('success-field').addClass('errors-field');
return;
}
const ageAtPassportIssue = passportDate.getFullYear() - dob.getFullYear();
// Проверка на возраст, в котором может быть выдан паспорт
if (ageAtPassportIssue > 12) {
// Если возраст при выдаче паспорта соответствует требованиям, подсвечиваем ячейку как успешную
$(this).parent().removeClass('errors-field').addClass('success-field');
} else {
// Если возраст не соответствует, показываем ошибку
$(this).parent().removeClass('success-field').addClass('errors-field');
}
});
$("#passport").attr('maxlength','12');
$('#passport').on('input', function() {
let input = $(this).val(); let input = $(this).val();
// Удаляем все символы, кроме цифр и пробелов // Удаляем все символы, кроме цифр
input = input.replace(/\D/g, ''); input = input.replace(/\D/g, '');
// Форматируем ввод в "00 00 000000" с пробелами
if (input.length > 2 && input.length <= 4) {
input = input.replace(/(\d{2})(\d{0,2})/, '$1 $2');
} else if (input.length > 4 && input.length <= 10) {
input = input.replace(/(\d{2})(\d{2})(\d{0,6})/, '$1 $2 $3');
}
// Ограничиваем длину до "00 00 000000"
if (input.length > 12) {
input = input.slice(0, 12);
}
// Обновляем поле ввода // Обновляем поле ввода
$(this).val(input); $(this).val(input);
// Проверка на минимальную длину (не менее 11 символов) // Проверка на минимальную длину (не менее 11 символов)
if (input.length < 12) { if (input.length < 4) {
// Если введено меньше цифр, показываем ошибку // Если введено меньше цифр, показываем ошибку
$(this).parent().removeClass('success-field').addClass('errors-field'); $(this).parent().removeClass('success-field').addClass('errors-field');
} else { } else {
@@ -148,89 +83,16 @@ $(document).ready(function(){
}); });
$('#postal_code').on('input', function() { $("#kod").attr('maxlength','4');
$('#kod').on('input', function() {
let input = $(this).val(); let input = $(this).val();
// Удаляем все символы, кроме цифр // Удаляем все символы, кроме цифр
input = input.replace(/\D/g, ''); input = input.replace(/\D/g, '');
// Форматируем ввод в "000-000" только при наличии 4 и более цифр
if (input.length > 3) {
input = input.replace(/(\d{3})(\d{0,3})/, '$1-$2');
}
// Ограничиваем длину до "000-000"
if (input.length > 7) {
input = input.slice(0, 7);
}
// Обновляем поле ввода // Обновляем поле ввода
$(this).val(input); $(this).val(input);
// Проверка на минимальную длину (не менее 11 символов) // Проверка на минимальную длину (не менее 11 символов)
if (input.length < 7) { if (input.length < 4) {
// Если введено меньше цифр, показываем ошибку
$(this).parent().removeClass('success-field').addClass('errors-field');
} else {
// Если введено достаточно цифр, показываем успех
$(this).parent().removeClass('errors-field').addClass('success-field');
}
});
$('#passport_issued_by').select2({
theme: 'bootstrap-5'
});
$("#postal_code").change(function(){
$('#passport_issued_by').empty();
$('#passport_issued_by').append('<option disabled="" selected="">Кем выдан паспорт</option>')
for(i in UFMS_list[$(this).val()])
{
item = UFMS_list[$(this).val()][i];
$('#passport_issued_by').append('<option>'+item+'</option>');
}
// $('#passport_issued_by').select2("change");
});
$('#snils').on('input', function() {
let input = $(this).val();
// Удаляем все символы, кроме цифр
input = input.replace(/\D/g, '');
// Форматируем ввод в "000-000-000-00" только после 3, 6, 9 цифр
if (input.length > 3 && input.length <= 6) {
input = input.replace(/(\d{3})(\d{0,3})/, '$1-$2');
} else if (input.length > 6 && input.length <= 9) {
input = input.replace(/(\d{3})(\d{3})(\d{0,3})/, '$1-$2-$3');
} else if (input.length > 9) {
input = input.replace(/(\d{3})(\d{3})(\d{3})(\d{0,2})/, '$1-$2-$3-$4');
}
// Ограничиваем длину до "000-000-000-00"
if (input.length > 14) {
input = input.slice(0, 14);
}
// Обновляем поле ввода
$(this).val(input);
if (input.length < 14) {
// Если введено меньше цифр, показываем ошибку
$(this).parent().removeClass('success-field').addClass('errors-field');
} else {
// Если введено достаточно цифр, показываем успех
$(this).parent().removeClass('errors-field').addClass('success-field');
}
});
$("#inn").attr('maxlength','12');
$('#inn').on('input', function() {
let input = $(this).val();
// Убираем все символы, кроме цифр
input = input.replace(/\D/g, '');
// Ограничиваем длину до 12 символов
if (input.length > 12) {
input = input.slice(0, 12);
}
// Обновляем значение в поле ввода
$(this).val(input);
if (input.length < 12) {
// Если введено меньше цифр, показываем ошибку // Если введено меньше цифр, показываем ошибку
$(this).parent().removeClass('success-field').addClass('errors-field'); $(this).parent().removeClass('success-field').addClass('errors-field');
} else { } else {
@@ -240,10 +102,12 @@ $(document).ready(function(){
}); });
$("#form_submit").click(function(){ $("#form_submit").click(function(){
$(this).children(".spinner-border").removeClass('d-none'); $(this).children(".spinner-border").removeClass('d-none');
$(this).attr("disabled", true); $(this).attr("disabled", true);
message = {} message = {}
if(!(validate_length($('#fio').val(), 3))) if(!(validate_length($('#fio').val(), 3)))
{ {
show_error('Введите ФИО', false); show_error('Введите ФИО', false);
@@ -260,81 +124,13 @@ $(document).ready(function(){
return; return;
} }
if ($('#dob').val().length !== 10 || new Date().getFullYear() - new Date($('#dob').val()).getFullYear() > 80) { if ($('#dob').val().length !== 4 || new Date().getFullYear() - new Date($('#dob').val()).getFullYear() > 80) {
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(!(validateEmail($('#email').val()))){
show_error('Введите корректный Email', false);
$(this).children(".spinner-border").addClass('d-none');
$(this).removeAttr("disabled");
return;
}
if(!(validate_length($('#passport').val(), 12)))
{
show_error('Введите серию и номер паспорта', false);
$(this).children(".spinner-border").addClass('d-none');
$(this).removeAttr("disabled");
return;
}
if ($('#passport_date').val().length !== 10 || (new Date($('#passport_date').val()).getFullYear() - new Date($('#dob').val()).getFullYear()) < 13) {
show_error('Проверьте дату выдачи паспорта, паспорт РФ может быть выдан с 14 лет', false);
$(this).children(".spinner-border").addClass('d-none');
$(this).removeAttr("disabled");
return;
}
if(!(validate_length($('#postal_code').val(), 7)))
{
show_error('Введите код подразделения', false);
$(this).children(".spinner-border").addClass('d-none');
$(this).removeAttr("disabled");
return;
}
if($('#passport_issued_by').val() == null){
show_error("Выберите кем выдан паспорт");
$(this).children(".spinner-border").addClass('d-none');
$(this).removeAttr("disabled");
return;
}
if(!(validate_length($('#address').val(), 3)))
{
show_error('Введите адрес регистрации', false);
$(this).children(".spinner-border").addClass('d-none');
$(this).removeAttr("disabled");
return;
}
if(!(validate_length($('#residential_address').val(), 3)))
{
show_error('Введите адрес проживания', false);
$(this).children(".spinner-border").addClass('d-none');
$(this).removeAttr("disabled");
return;
}
if(!(validate_length($('#snils').val(), 14)))
{
show_error('Введите СНИЛС', false);
$(this).children(".spinner-border").addClass('d-none');
$(this).removeAttr("disabled");
return;
}
if(!(validate_length($('#inn').val(), 12)))
{
show_error('Введите ИНН', false);
$(this).children(".spinner-border").addClass('d-none');
$(this).removeAttr("disabled");
return;
}