Compare commits

...

2 Commits

Author SHA1 Message Date
bc4a602daa Добавил посхалку на 1е апреля
All checks were successful
Build and deploy / Publish image (push) Successful in 4m30s
2025-03-10 03:59:18 +03:00
e090e7f834 Выход из альфы 2025-03-10 03:58:54 +03:00
5 changed files with 130 additions and 7 deletions

View File

@@ -7,7 +7,7 @@
- [ ] Сделать обновление валидации от radiobutton
- [ ] Добавить направления других институтов
- [ ] Найти шаблоны других институтов и написать выбор шаблонов
- [ ] Рефактор кода
- [x] Рефактор кода
# Лицензия

View File

@@ -0,0 +1,118 @@
@page "/fstaprl"
@inject AuthenticationStateProvider AuthenticationStateProvider
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using NPetrovich
@using Otchinslator.Services
@attribute [Authorize]
@inject IStatementGenerator StatementGenerator
<PageTitle>Заяление отправлено | 1 апреля</PageTitle>
@code {
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var userEmail = authState.User.Identity.Name;
var userFIO = authState.User.Claims.FirstOrDefault(x => x.Type == "name")?.Value;
var petrovich = new Petrovich()
{
FirstName = userFIO.Split(' ')[0],
LastName = userFIO.Split(' ')[1],
MiddleName = userFIO.Split(' ').Length > 2 ? userFIO.Split(' ')[2] : "",
Gender = Gender.Male
};
userFIO = petrovich.InflectFirstNameTo(Case.Genitive) + " " + petrovich.InflectLastNameTo(Case.Genitive) + " " + petrovich.InflectMiddleNameTo(Case.Genitive);
var userData = new UserData
{
reason = "Прошу отчислить меня по собственному желанию в связи с не желанием продолжать обучение в данном учебном заведении, планирую перевестись в ДГТУ.",
email = userEmail,
phone = "",
fio = userFIO,
kurs = 1,
isFreeEducation = true,
isOchno = true,
speciality = SpecialityType.Bakalavriat,
direction = ""
};
var statement = await StatementGenerator.GenerateStatementAsync(userData, "frstaprl.docx");
var pdf = await StatementGenerator.ConvertToPDFAsync(statement);
await using var fileStream = new FileStream("./PDFCache/" + userEmail.Split('@')[0] + ".pdf", FileMode.Create, FileAccess.Write);
await pdf.CopyToAsync(fileStream);
}
}
<dialog id="denyModal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<h3 class="text-lg font-bold text-center">С 1 апреля!</h3>
@* <p class="py-4 font-bold text-center"></p> *@
<img src="https://risovach.ru/upload/2013/04/mem/moe-lico_15228723_orig_.jpeg" class="h-80 my-2 mx-auto"
alt=""/>
@* <p class="text-center">.</p> *@
<div class="modal-action justify-center">
<form method="dialog">
<button class="btn btn-primary">Понял, принял</button>
</form>
</div>
</div>
</dialog>
<div class="relative">
<div
class="text-center font-bold text-3xl md:text-5xl w-max absolute left-1/2 -top-1/4 transform -translate-x-1/2 italic">
<br>Заявление на отчисление<p class="text-2xl font-normal">отправлено директору</p>
</div>
<div id="pdfrenderer">
<object data="/getStatement" type="application/pdf" class="w-96 sm:w-[32rem] h-[30rem] rounded-2xl text-center">
<p>Не удалось отобразить заявление</p>
<button id="alterRender" class="btn btn-primary my-2">использовать альтернативную отрисовку</button>
<p>или откойте в браузере на основе Firefox</p>
</object>
</div>
<div class="join w-full mt-4 flex gap-2">
<button onclick="denyModal.showModal()" class="btn btn-error rounded-full flex-grow w-30">
Отозвать
</button>
<a id="downloadPDF" target="_blank" href="/getStatement"
class="btn btn-primary bg-base-200 border-base-200 rounded-full flex-grow-0 w-[3rem]">
@* Скачать PDF *@
<div class="absolute rounded-full w-12 h-12">
<img class="p-3" src="img/pdf.svg" alt=""/>
</div>
</a>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.10.377/pdf.min.js"></script>
<script>
const alterRenderButton = document.getElementById('alterRender');
alterRenderButton.addEventListener('click', alterRender);
function alterRender() {
const pdfrenderer = document.getElementById('pdfrenderer');
const url = '/getStatement';
pdfrenderer.innerHTML = '<canvas id="pdf-canvas" class="w-96 rounded-2xl"></canvas>';
pdfjsLib.getDocument(url).promise.then(function (pdf) {
pdf.getPage(1).then(function (page) {
const viewport = page.getViewport({scale: 1});
const canvas = document.getElementById('pdf-canvas');
const context = canvas.getContext('2d');
canvas.width = viewport.width;
canvas.height = viewport.height;
const renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
});
});
}
</script>

View File

@@ -5,13 +5,17 @@
<PageTitle>Отчислятор 3000</PageTitle>
<JS For="this" Args="[AuthenticationStateProvider.GetAuthenticationStateAsync().Result.User.Identity?.IsAuthenticated]" />
<JS For="this"
Args="[AuthenticationStateProvider.GetAuthenticationStateAsync().Result.User.Identity?.IsAuthenticated]"/>
<div class="relative">
<dialog id="info_modal" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<h3 class="text-lg font-bold">Сервис отчислений</h3>
<p class="py-4">Привет, это НЕОФИЦИАЛЬНЫЙ сервис отчислений!<br><br>Авторизуясь Вы соглашаетесь передать личные данные, такие как email + фио (из авторизации ЮФУ), и все остальные запрошенные далее. На нашем сервере хранятся только Ваши сгенерированные pdf заявления, другая информация сохраняется только в браузере.<br><br>Автор: <a target="_blank" href="https://t.me/serega404">@@serega404</a></p>
<p class="py-4">Привет, это НЕОФИЦИАЛЬНЫЙ сервис отчислений!<br><br>Авторизуясь Вы соглашаетесь передать
личные данные, такие как email + фио (из авторизации ЮФУ), и все остальные запрошенные далее. На нашем
сервере хранятся только Ваши сгенерированные pdf заявления, другая информация сохраняется только в
браузере.<br><br>Автор: <a target="_blank" href="https://t.me/serega404">@@serega404</a></p>
<div class="modal-action">
<form method="dialog">
<button class="btn">Закрыть</button>
@@ -37,7 +41,7 @@
<div
class="text-center font-bold text-4xl md:text-5xl w-max absolute left-1/2 -top-1/2 transform -translate-x-1/2 italic">
<br>Отчислятор 3000<br>
<p class="text-2xl text-red-500">alpha</p></div>
</div>
<div class="flex flex-col space-y-4 w-96">
<div class="card rounded-badge bg-base-200 p-4">
@* <h2 class="card-title text-center text-3xl justify-center my-4">Мне нужно...</h2> *@

View File

@@ -8,7 +8,7 @@ namespace Otchinslator.Services;
public interface IStatementGenerator
{
public Task<MemoryStream> GenerateStatementAsync(UserData userData);
public Task<MemoryStream> GenerateStatementAsync(UserData userData, string TemplateName = "ictis.docx");
public Task<Stream> ConvertToPDFAsync(MemoryStream stream);
}
@@ -21,9 +21,10 @@ public class StatementGenerator(GotenbergSharpClient gotenbergSharpClient) : ISt
private const string FreeEducationText = "за счет ассигнований федерального бюджета";
private const string PaidEducationText = "на договорной (платной) основе";
public async Task<MemoryStream> GenerateStatementAsync(UserData userData)
// TODO: Выбор темплейтов не реализован
public async Task<MemoryStream> GenerateStatementAsync(UserData userData, string TemplateName = "ictis.docx")
{
byte[] textByteArray = File.ReadAllBytes("Templates/ictis.docx");
byte[] textByteArray = File.ReadAllBytes("Templates/" + TemplateName);
MemoryStream stream = new MemoryStream();
stream.Write(textByteArray, 0, textByteArray.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true))

Binary file not shown.