123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- @page "/pageprojetoFileStream/{projetoCodigo:guid}"
- @attribute [Authorize]
- @rendermode InteractiveServer
- @using System.ComponentModel.DataAnnotations
- @using System.Text
- @using System.Text.Encodings.Web
- @using ConcursoProjetos.Service
- @using Microsoft.AspNetCore.Identity
- @using Microsoft.AspNetCore.WebUtilities
- @using System;
- @using System.IO;
- @inject UserManager<ApplicationUser> UserManager
- @inject AuthenticationStateProvider AuthenticationStateProvider
- @inject ICandidatoService candidatoService
- @inject IProjetoService projetoService
- @inject IDocumentoService documentoService
- @inject ITipoDocumentoService tipoDocumentoServico
- @inject DialogService dialogService
- @inject NotificationService notificationService
- @inject NavigationManager Navigation
- <PageTitle>Cadastro de Projeto</PageTitle>
- <div class="container mt-5">
- <h3>Cadastro de Projeto</h3>
- <br />
- <RadzenTemplateForm TItem="InputModel" Data=@Input Submit=@OnSubmit InvalidSubmit=@OnInvalidSubmit>
- <RadzenRow Gap="1rem">
- <RadzenColumn Size="12" SizeSM="6">
- <RadzenStack>
- <RadzenFormField Text="Nome do Projeto" Variant="@variant">
- <RadzenTextBox Name="Nome" @bind-Value="@Input.Nome" />
- <RadzenRequiredValidator Component="Nome" Text="Nome do projeto é obrigatório" Popup=@popup Style="position: relative" />
- </RadzenFormField>
- <RadzenFormField Text="Nome do Responsável Técnico da Empresa" Variant="@variant">
- <RadzenTextBox Name="ResponsavelNome" @bind-Value="@Input.ResponsavelTecnicoNomeCompleto" />
- <RadzenRequiredValidator Component="ResponsavelNome" Text="Nome do responsável técnico é obrigatório" Popup=@popup Style="position: relative" />
- </RadzenFormField>
- <RadzenFormField Text="CPF do Responsável Técnico da Empresa" Variant="@variant">
- <RadzenMask Mask="***.***.***-**" CharacterPattern="[0-9]" Placeholder="000.000.000-00" Name="ResponsavelTecnicoCpf" @bind-Value="Input.ResponsavelTecnicoCpf" />
- <RadzenRequiredValidator Component="ResponsavelTecnicoCpf" Text="Cpf do responsável técnico é obrigatório" Popup=@popup Style="position: relative" />
- </RadzenFormField>
- </RadzenStack>
- </RadzenColumn>
- <RadzenColumn Size="12" SizeSM="6">
- <RadzenStack>
- <RadzenFormField Text="Número de Unidades Habitacionais por Pavimento" Variant="@variant">
- <RadzenDropDown @bind-Value="@Input.NumeroUnidades" Data="@listaDeUnidades" />
- </RadzenFormField>
- <RadzenFormField Text="E-mail do Responsável Técnico da Empresa" Variant="@variant">
- <RadzenTextBox Name="Email" @bind-Value="@Input.ResponsavelTecnicoEmail" />
- <RadzenRequiredValidator Component="Email" Text="E-mail é obrigatório" Popup=@popup Style="position: relative" />
- <RadzenEmailValidator Component="Email" Text="Informe um e-mail válido" Popup=@popup Style="position: relative" />
- </RadzenFormField>
- <RadzenFormField Text="Telefone do Responsável Técnico da Empresa" Variant="@variant">
- <RadzenMask Mask="(**) *****-****" CharacterPattern="[0-9]" Placeholder="(00) 00000-0000" Name="ResponsavelTecnicoTelefone" @bind-Value="Input.ResponsavelTecnicoTelefone" />
- <RadzenRequiredValidator Component="ResponsavelTecnicoTelefone" Text="Telefone do responsável técnico é obrigatório" Popup=@popup Style="position: relative" />
- </RadzenFormField>
- </RadzenStack>
- </RadzenColumn>
- </RadzenRow>
- <RadzenRow AlignItems="AlignItems.Center" class="rz-mt-4">
- <RadzenColumn Size="12" Offset="0" SizeMD="8" OffsetMD="4">
- <RadzenButton ButtonType="ButtonType.Submit" Text="@rotuloBotaoGravar"></RadzenButton>
- </RadzenColumn>
- </RadzenRow>
- </RadzenTemplateForm>
- <!-- Seção para envio de anexos -->
- @if (_projeto != null && _candidato != null && _documentosModel != null)
- {
- <h4 class="mt-4">Envio de Anexos</h4>
- <div class="table-responsive">
- <table class="table table-bordered">
- <thead>
- <tr>
- <th>Tipo de Arquivo</th>
- <th>Escolher o Arquivo</th>
- <th>Status</th>
- </tr>
- </thead>
- <tbody>
- @foreach (var model in _documentosModel)
- {
- <tr>
- <td><strong>@model.TipoDocumento.Nome</strong></td>
- <td>
- <InputFile disabled="@UploadingLargeFile" OnChange="@((args) => OnLargeFileInputFileChange(args, _candidato, _projeto, model))" />
- @if ((listaTipoDocumentoLoading.Count > 0) && listaTipoDocumentoLoading.Where(x => x.TipoDocumento.Id == model.TipoDocumento.Id).First().Uploading)
- {
- <progress style="height:50px;width:100%;" value="@UploadedBytes" max="@TotalBytes"></progress>
- }
- </td>
- <td>
- @if (model.Status)
- {
- <i class="bi bi-check-all fs-5 text-success"></i>
- }
- else
- {
- <i class="bi bi-x fs-5 text-danger"></i>
- }
- </td>
- </tr>
- }
- </tbody>
- </table>
- </div>
- }
- </div>
- @code {
- bool popup;
- Variant variant = Variant.Outlined;
- bool Uploading = false;
- bool UploadingLargeFile = false;
- string LargeUploadMessage = "";
- long UploadedBytes;
- long TotalBytes;
- async Task OnLargeFileInputFileChange(InputFileChangeEventArgs args, Candidato candidato, Projeto projeto, InputModelDocuments modelDocument)
- {
- Documento resultado;
- // UploadedBytes = 0;
- // Disable the file input field
- //UploadingLargeFile = true;
- var tipoDocumentoLoading = listaTipoDocumentoLoading.Where(x => x.TipoDocumento.Id == modelDocument.TipoDocumento.Id).First();
- tipoDocumentoLoading.Uploading = true;
- await InvokeAsync(StateHasChanged);
- // calculate the chunks we have to send
- TotalBytes = args.File.Size;
- long percent = 0;
- long chunkSize = 1000000;
- long numChunks = TotalBytes / chunkSize;
- long remainder = TotalBytes % chunkSize;
- // get new filename with a bit of entropy
- string justFileName = Path.GetFileNameWithoutExtension(args.File.Name);
- string extension = Path.GetExtension(args.File.Name);
- string newFileNameWithoutPath = $"Projeto_{projeto.Id}_{modelDocument.TipoDocumento.Nome}-{justFileName}-{DateTime.Now.Ticks.ToString()}{extension}";
- //string projectPath = $"{Environment.CurrentDirectory}\\files\\{projeto.Id}";
- string projectPath = projetoService.Path(projeto.Id);
- string filename = $"{projectPath}\\{newFileNameWithoutPath}";
- if (!Directory.Exists(projectPath))
- {
- Directory.CreateDirectory(projectPath);
- GerarArquivoTextoParaProjeto(candidato, projeto, projectPath);
- }
- // Delete the file if it already exists in our \Files folder
- if (File.Exists(filename))
- {
- File.Delete(filename);
- }
- // Open the input and output file streams
- // using (var inStream = args.File.OpenReadStream(long.MaxValue))
- // {
- // using (var outStream = File.OpenWrite(filename))
- // {
- // while (UploadedBytes < TotalBytes)
- // {
- // var whatsLeft = TotalBytes - UploadedBytes;
- // if (whatsLeft < chunkSize)
- // chunkSize = remainder;
- // // Read the next chunk
- // var bytes = new byte[chunkSize];
- // var buffer = new Memory<byte>(bytes);
- // var read = await inStream.ReadAsync(buffer);
- // // Write it
- // await outStream.WriteAsync(bytes, 0, read);
- // // Update our progress data and UI
- // UploadedBytes += read;
- // percent = UploadedBytes * 100 / TotalBytes;
- // // Report progress with a string
- // LargeUploadMessage = $"Uploading {args.File.Name} {percent}%";
- // await InvokeAsync(StateHasChanged);
- // }
- // }
- // }
- var file = args.File;
- var buffer = new byte[1 * 1024 * 1024]; // 80 KB buffer size 1 * 1024 * 1024
- var totalRead = 0L;
- using (var inStream = file.OpenReadStream(long.MaxValue))
- using (var outStream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None))
- {
- while (totalRead < file.Size)
- {
- var read = await inStream.ReadAsync(buffer, 0, buffer.Length);
- if (read == 0)
- break;
- await outStream.WriteAsync(buffer, 0, read);
- totalRead += read;
- // Atualize o progresso se necessário
- percent = (int)((totalRead * 100) / file.Size);
- LargeUploadMessage = $"Uploading {args.File.Name} {percent}%";
- Console.WriteLine($"Uploading {file.Name} {percent}%");
- }
- }
- LargeUploadMessage = "Upload Completo.";
- //await ListFiles();
- Documento documentoGravado = new()
- {
- Descricao = "",
- ArquivoNomeOriginal = newFileNameWithoutPath,
- ArquivoTamanhoBytes = TotalBytes,
- ProjetoId = projeto.Id,
- TipoDocumentoId = modelDocument.TipoDocumento.Id,
- UploadCompleto = true
- };
- if (documentoGravado.Id > 0) // Alteração
- {
- documentoGravado.AtribuiId(modelDocument.DocumentoId);
- }
- resultado = documentoService.Gravar(documentoGravado);
- //UploadingLargeFile = false;
- tipoDocumentoLoading.Uploading = false;
- bool uploadIncompletosAntes = _documentosModel.Any(x => !x.Status);
- AtualizarListaDocumentos();
- bool uploadIncompletosDepois = _documentosModel.Any(x => !x.Status);
- if (uploadIncompletosAntes && !uploadIncompletosDepois)
- {
- //"Seu projeto foi enviado com sucesso.Caso deseje realizar alguma alteração, o projeto estará listado na área 'meus projetos'"
- await dialogService.Alert("Seu projeto foi enviado com sucesso. <br />Caso deseje realizar alguma alteração, o projeto estará listado na área 'Meus Projetos'.",
- "Projeto Enviado",
- new AlertOptions() { OkButtonText = "Ok" });
- Navigation.NavigateTo($"/gestaoprojetos");
- return;
- }
- if (!uploadIncompletosAntes)
- {
- // "Deseja alterar mais algum anexo enviado?
- // sim => permanece na tela
- // não => exibe mensagem anterior "primeira vez que ele completa."
- bool? result = await dialogService.Confirm("Deseja alterar mais algum anexo enviado?",
- "Anexo Enviado com Sucesso",
- new ConfirmOptions() { OkButtonText = "Yes", CancelButtonText = "No" });
- if (result != true)
- {
- await dialogService.Alert("Seu projeto foi enviado com sucesso.</p>Caso deseje realizar alguma alteração, o projeto estará listado na área 'Meus Projetos'",
- "Projeto Enviado",
- new AlertOptions() { OkButtonText = "Ok" });
- Navigation.NavigateTo($"/gestaoprojetos");
- return;
- }
- return;
- }
- }
- private void GerarArquivoTextoParaProjeto(Candidato candidato, Projeto projeto, string path)
- {
- string saudacao = $@"
- Candidado:
- Nome......: {candidato.NomeCompleto}
- E-mail....: {candidato.Email}
- Telefone..: {candidato.Email}
- ";
- if (candidato.TipoPessoa) // Representa empresa
- {
- saudacao += $@"
- Empresa:
- Nome....: {candidato.EmpresaRazaoSocial}
- E-mail..: {candidato.EmpresaEmail}
- Telefone..: {candidato.EmpresaTelefone}";
- }
- saudacao += $@"
- Projeto '{projeto.Nome}':
- Responsável.....: {projeto.ResponsavelTecnicoNomeCompleto}
- E-mail...: {projeto.ResponsavelTecnicoEmail}
- Telefone.: {projeto.ResponsavelTecnicoTelefone}";
- string fullPath = Path.Combine(path, "config.txt");
- File.WriteAllText(fullPath, saudacao);
- }
- [Parameter]
- public Guid projetoCodigo { get; set; }
- private Candidato? _candidato;
- private Projeto? _projeto;
- private IEnumerable<Documento>? _documentos;
- private IEnumerable<InputModelDocuments>? _documentosModel;
- private string _mensagem = "Loading...";
- private long candidatoId;
- private string rotuloBotaoGravar = "Enviar";
- //private long projetoId = 5;
- List<ModelTipoDocumento> listaTipoDocumentoLoading = new();
- [SupplyParameterFromForm]
- private InputModel Input { get; set; } = new();
- private List<int> listaDeUnidades = Enumerable.Range(2, 31).ToList();
- protected override async Task OnInitializedAsync()
- {
- var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
- var user = authState.User;
- if (user.Identity.IsAuthenticated)
- {
- var identityUser = await UserManager.GetUserAsync(user);
- if (identityUser != null)
- {
- _candidato = candidatoService.ObterPorUserID(identityUser.Id);
- }
- }
- if (projetoCodigo != Guid.Empty)
- {
- _projeto = projetoService.ObterPorCodigo(projetoCodigo);
- _documentos = documentoService.Listar(_projeto.Id);
- AtualizarModel(_projeto);
- rotuloBotaoGravar = "Alterar Dados do Projeto Cadastrado";
- }
- AtualizarListaDocumentos();
- var listaTipo = tipoDocumentoServico.Listar();
- foreach (var tipo in listaTipo)
- listaTipoDocumentoLoading.Add(new ModelTipoDocumento { TipoDocumento = tipo, Uploading = false });
- }
- private void AtualizarModel(Projeto projeto)
- {
- Input.Id = projeto.Id;
- Input.Nome = projeto.Nome;
- Input.NumeroUnidades = projeto.NumeroUnidades;
- Input.ResponsavelTecnicoCpf = projeto.ResponsavelTecnicoCpf;
- Input.ResponsavelTecnicoNomeCompleto = projeto.ResponsavelTecnicoNomeCompleto;
- Input.ResponsavelTecnicoTelefone = projeto.ResponsavelTecnicoTelefone;
- Input.ResponsavelTecnicoEmail = projeto.ResponsavelTecnicoEmail;
- }
- private async Task OnSubmit(InputModel model)
- {
- Projeto resultado;
- Projeto projeto = new(_candidato.Id)
- {
- Codigo = Guid.NewGuid(),
- Nome = Input.Nome,
- NumeroUnidades = Input.NumeroUnidades,
- ResponsavelTecnicoCpf = Input.ResponsavelTecnicoCpf.Replace(".", "").Replace("-", ""),
- ResponsavelTecnicoNomeCompleto = Input.ResponsavelTecnicoNomeCompleto,
- ResponsavelTecnicoTelefone = Input.ResponsavelTecnicoTelefone,
- ResponsavelTecnicoEmail = Input.ResponsavelTecnicoEmail
- };
- if (_projeto != null) // Alteração
- {
- projeto.AtribuiId(_projeto.Id);
- resultado = projetoService.Alterar(projeto);
- }
- else // Inclusão
- {
- resultado = projetoService.Adicionar(projeto);
- rotuloBotaoGravar = "Alterar Dados do Projeto Cadastrado";
- }
- if (resultado != null)
- {
- _projeto = resultado;
- projetoCodigo = resultado.Codigo;
- MontarModelDocuments();
- NotificationMessage message = new NotificationMessage
- {
- Severity = NotificationSeverity.Info,
- Summary = "Projeto gravado com sucesso.",
- Detail = "",
- Duration = 3000
- };
- notificationService.Notify(message);
- }
- StateHasChanged();
- }
- private async void OnInvalidSubmit(FormInvalidSubmitEventArgs args)
- {
- //Log("InvalidSubmit", JsonSerializer.Serialize(args, new JsonSerializerOptions() { WriteIndented = true }));
- }
- private void AtualizarListaDocumentos()
- {
- if (_projeto == null || _projeto.Id <= 0)
- return;
- _documentos = documentoService.Listar(_projeto.Id);
- MontarModelDocuments();
- StateHasChanged();
- }
- private void MontarModelDocuments()
- {
- List<InputModelDocuments> resultado = new();
- var listaTipo = tipoDocumentoServico.Listar();
- foreach (TipoDocumento tipo in listaTipo)
- {
- long documentoId = 0;
- bool status = false;
- if (_documentos != null && _documentos.Count() > 0)
- {
- var ProjetoPossuiDocumento = _documentos.Where(d => d.TipoDocumentoId == tipo.Id).SingleOrDefault();
- if (ProjetoPossuiDocumento != null)
- {
- documentoId = ProjetoPossuiDocumento.Id;
- status = true;
- }
- }
- resultado.Add(new InputModelDocuments
- {
- DocumentoId = documentoId,
- TipoDocumento = tipo,
- Status = status
- });
- }
- _documentosModel = resultado;
- }
- private sealed class InputModel
- {
- public long Id { get; set; }
- [Required]
- [StringLength(100, MinimumLength = 5)]
- [Display(Name = "Nome do Projeto")]
- public string Nome { get; set; } = "";
- [Required]
- [Range(2, 32, ErrorMessage = "O valor deve estar entre 2 e 32.")]
- [Display(Name = "Número de Unidades Habitacionais por Pavimento")]
- public int NumeroUnidades { get; set; } = 2;
- [Required]
- [MaxLength(100)]
- [Display(Name = "Nome do Responsável Técnico da Empresa")]
- public string ResponsavelTecnicoNomeCompleto { get; set; }
- [Required]
- [MaxLength(100)]
- [EmailAddress]
- [Display(Name = "E-mail do Responsável Técnico da Empresa")]
- public string ResponsavelTecnicoEmail { get; set; }
- [Required]
- [MaxLength(14)]
- [Display(Name = "CPF do Responsável Técnico da Empresa")]
- public string ResponsavelTecnicoCpf { get; set; }
- [Required]
- [MaxLength(20)]
- [Display(Name = "Telefone do Responsável Técnico da Empresa")]
- public string ResponsavelTecnicoTelefone { get; set; }
- }
- private sealed class InputModelDocuments
- {
- public long DocumentoId { get; set; }
- public TipoDocumento TipoDocumento { get; set; }
- //public DateTime DataInclusao { get; set; }
- public bool Status { get; set; }
- }
- private sealed class ModelTipoDocumento
- {
- public TipoDocumento TipoDocumento { get; set; }
- public bool Uploading { get; set; }
- }
- }
|