added API VICON integration for updating admission plans via admin panel (queued).

Updated exams and contests display on programs/show page.
Added relevant enums for admission plans.
This commit is contained in:
F4ilji
2025-04-09 15:58:29 +05:00
parent 7793d078e9
commit 88e729aa87
19 changed files with 684 additions and 100 deletions
+91 -6
View File
@@ -1,6 +1,80 @@
class EducationForm {
static BUDGET_QUANTITY_POSITION = { value: 1, label: 'Бюджетные места', color: 'info', name: 'BUDGET_QUANTITY_POSITION' };
static NON_BUDGET_QUANTITY_POSITION = { value: 2, label: 'С оплатой обучения', color: 'primary', name: 'NON_BUDGET_QUANTITY_POSITION' };
static MAIN_QUOTA = {
value: 1,
label: 'Основные места',
color: 'primary',
name: 'MAIN_QUOTA'
};
static TARGET_QUOTA = {
value: 2,
label: 'Целевая квота',
color: 'info',
name: 'TARGET_QUOTA'
};
static SPECIAL_QUOTA = {
value: 3,
label: 'Особая квота',
color: 'danger',
name: 'SPECIAL_QUOTA'
};
static PAID_EDUCATION = {
value: 4,
label: 'С оплатой обучения',
color: 'warning',
name: 'PAID_EDUCATION'
};
static OTHER_SOURCES = {
value: 5,
label: 'За счёт иных средств',
color: 'gray',
name: 'OTHER_SOURCES'
};
static SEPARATE_QUOTA = {
value: 6,
label: 'Отдельная квота',
color: 'success',
name: 'SEPARATE_QUOTA'
};
static COMBINED_QUOTA_ALL = {
value: 7,
label: 'Совмещенная квота (целевая, особая и отдельная квоты)',
color: 'indigo',
name: 'COMBINED_QUOTA_ALL'
};
static COMBINED_QUOTA_TARGET_SPECIAL = {
value: 8,
label: 'Совмещенная квота (целевая и особая квоты)',
color: 'violet',
name: 'COMBINED_QUOTA_TARGET_SPECIAL'
};
static COMBINED_QUOTA_TARGET_SEPARATE = {
value: 9,
label: 'Совмещенная квота (целевая и отдельная квоты)',
color: 'fuchsia',
name: 'COMBINED_QUOTA_TARGET_SEPARATE'
};
static COMBINED_QUOTA_SPECIAL_SEPARATE = {
value: 10,
label: 'Совмещенная квота (особая и отдельная квоты)',
color: 'pink',
name: 'COMBINED_QUOTA_SPECIAL_SEPARATE'
};
static DETAILED_TARGET_QUOTA = {
value: 11,
label: 'Детализированная целевая квота',
color: 'amber',
name: 'DETAILED_TARGET_QUOTA'
};
// Метод для получения статуса по имени
static fromName(name) {
@@ -11,10 +85,21 @@ class EducationForm {
return Object.values(this).find(item => item.value == value) || null;
}
// Метод для получения имени
getName() {
return this.name;
// Метод для получения всех значений
static getAll() {
return [
this.MAIN_QUOTA,
this.TARGET_QUOTA,
this.SPECIAL_QUOTA,
this.PAID_EDUCATION,
this.OTHER_SOURCES,
this.SEPARATE_QUOTA,
this.COMBINED_QUOTA_ALL,
this.COMBINED_QUOTA_TARGET_SPECIAL,
this.COMBINED_QUOTA_TARGET_SEPARATE,
this.COMBINED_QUOTA_SPECIAL_SEPARATE,
this.DETAILED_TARGET_QUOTA
];
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
class EducationForm {
static FULL_TIME = { value: 1, label: 'Очное обучение', color: 'info', name: 'FULL_TIME', type_label: 'Форма обучения' };
static PART_TIME = { value: 2, label: 'Заочное обучение', color: 'primary', name: 'PART_TIME', type_label: 'Форма обучения' };
static FULL_PART_TIME = { value: 3, label: 'Очно-заочное обучение', color: 'success', name: 'FULL_PART_TIME', type_label: 'Форма обучения' };
static FULL_PART_TIME = { value: 2, label: 'Очно-заочное обучение', color: 'success', name: 'FULL_PART_TIME', type_label: 'Форма обучения' };
static PART_TIME = { value: 3, label: 'Заочное обучение', color: 'primary', name: 'PART_TIME', type_label: 'Форма обучения' };
// Метод для получения статуса по имени
static fromName(name) {
+48
View File
@@ -0,0 +1,48 @@
class TypeExam {
static EGE = {
value: 1,
label: 'ЕГЭ',
color: 'primary',
name: 'EGE'
};
static INTERNAL_EXAM = {
value: 2,
label: 'Вступительное испытание',
color: 'info',
name: 'INTERNAL_EXAM'
};
static AVG_SCORE = {
value: 3,
label: 'Ср. балл аттестата',
color: 'success',
name: 'AVG_SCORE'
};
static ACCREDITATION = {
value: 4,
label: 'Аккредитация',
color: 'warning',
name: 'ACCREDITATION'
};
static fromName(name) {
return this[name] || null;
}
static fromValue(value) {
return Object.values(this).find(item => item.value == value) || null;
}
static getAll() {
return [
this.EGE,
this.INTERNAL_EXAM,
this.AVG_SCORE,
this.ACCREDITATION
];
}
}
export default TypeExam;
+42 -13
View File
@@ -10,6 +10,7 @@ import BasicTitle from "@/componentss/ui/titles/BasicTitle.vue";
import ProgramItemBreadcrumbs from "@/componentss/features/educationalPrograms/components/ProgramItemBreadcrumbs.vue";
import ProgramTitle from "@/componentss/features/educationalPrograms/components/ProgramTitle.vue";
import BudgetEducation from "@/Enum/BudgetEducation.js";
import TypeExam from "@/Enum/TypeExam.js";
export default {
@@ -21,10 +22,28 @@ export default {
BudgetForm() {
return BudgetEducation
},
TypeExam() {
return TypeExam
},
},
methods: {
typeExam(type) {
return (type === 'ege' ? 'ЕГЭ' : 'ВИ')
groupExamsByPriority(exams) {
return exams.reduce((groups, exam) => {
if (!groups[exam.priority]) {
groups[exam.priority] = [];
}
groups[exam.priority].push(exam);
return groups;
}, {});
},
groupContestsByFormEducation(contests) {
return contests.reduce((groups, contest) => {
if (!groups[contest.form_education]) {
groups[contest.form_education] = [];
}
groups[contest.form_education].push(contest);
return groups;
}, {});
}
},
components: {
@@ -119,10 +138,12 @@ export default {
<div class="mt-3">
<h3 class="text-lg font-semibold text-gray-800">Количество мест на прием</h3>
<template v-for="admissionPlan in program.data.admissionPlans">
<template v-for="contest in admissionPlan.contests">
<template v-for="(contests, form) in groupContestsByFormEducation(admissionPlan.contests)">
<div class="border rounded my-2 py-1">
<span class="text-gray-500 text-[14px]">{{ EducationForm.fromValue(contest.form_education).label }}</span>
<p v-for="place in contest.places" class="mt-1 text-gray-600"> {{ place.count }} мест <span class="text-gray-400 text-[12px]">{{ BudgetForm.fromValue(place.form_budget).label }}</span></p>
<span class="text-gray-500 text-[14px]">{{ EducationForm.fromValue(form).label }}</span>
<template v-for="contest in contests">
<p class="mt-1 text-gray-600"> {{ contest.places.count }} мест <span class="text-gray-400 text-[12px]">{{ BudgetForm.fromValue(contest.places.form_budget).label }}</span></p>
</template>
</div>
</template>
@@ -148,14 +169,22 @@ export default {
</button>
<div id="hs-basic-bordered-collapse-two" class="hs-accordion-content hidden w-full overflow-hidden transition-[height] duration-300" aria-labelledby="hs-bordered-heading-two">
<div class="pb-4 px-5">
<ol class="list-decimal list-inside">
<template v-for="admissionPlan in program.data.admissionPlans">
<template v-for="exam in admissionPlan.exams">
<li>{{ exam.title }} <span v-for="ex in exam.exam" class="text-gray-400 text-[14px]">({{ typeExam(ex.type_exam) }}, минимальный балл: {{ ex.min_score }}) </span></li>
</template>
</template>
</ol>
</div>
<ol class="list-decimal list-inside">
<template v-for="admissionPlan in program.data.admissionPlans">
<template v-for="(exams, priority) in groupExamsByPriority(admissionPlan.exams)">
<li>
<template v-for="(exam, index) in exams">
{{ exam.title }}
<span v-for="ex in exam.types" class="text-gray-400 text-[14px]">
({{ TypeExam.fromValue(ex.type).label }}, минимальный балл: {{ ex.min_ball }})
</span>
<span class="text-gray-400 text-[14px] uppercase" v-if="index !== exams.length - 1"><br> или </span>
</template>
</li>
</template>
</template>
</ol>
</div>
</div>
</div>