123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- using Microsoft.AspNetCore.Components;
- using Microsoft.AspNetCore.Components.Authorization;
- using Microsoft.AspNetCore.Components.Forms;
- using Microsoft.AspNetCore.Identity;
- using Microsoft.JSInterop;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel.DataAnnotations;
- using System.IO;
- using System.Reflection;
- using System.Threading.Tasks;
- using System.Linq;
- using System.Net;
- using System.Security.Cryptography;
- using HyperCube.Models;
- using Console = HyperCube.Utils.AdvConsole;
- namespace HyperCube.Pages
- {
- public partial class DocEdit : ComponentBase
- {
- [Parameter]
- public int DocID { get; set; }
- [Inject]
- public NavigationManager NavigationManager { get; set; }
- [Inject]
- public IJSRuntime JsRuntime { get; set; }
- [Inject]
- public AuthenticationStateProvider AuthenticationStateProvider { get; set; }
- [Inject]
- public UserManager<IdentityUser> UserManager { get; set; }
- const string FOLDER_NAME = "articles_storage";
- const long MAX_FILE_SIZE = 5120000; //bytes
- string transactionId;
- ArticleModel articleClone = new();
- ArticleModel article = new();
- AccountModel currentAcc = new();
- AccountModel initiatorAcc = new();
- string status;
- string header;
- string storageFolderPath;
- MemoryStream memoryStream;
- ModalInfo modalInfo_error { get; set; }
- ModalInfo modalInfo_transac { get; set; }
- ModalLoading modalLoading { get; set; }
- string fullName { get { return FOLDER_NAME + "/" + article.FilenameReal; } }
- int editsCount;
- bool IsSubmitDisabled = false;
- protected override async Task OnInitializedAsync()
- {
- currentAcc = await GetCurrentAcc();
- string path = AppDomain.CurrentDomain.BaseDirectory+@"wwwroot";
- storageFolderPath = (Path.Combine(path, FOLDER_NAME));
- Console.WriteLine("docedit OnInitializedAsync storageFolderPath2 " + storageFolderPath);
- if (DocID > 0)
- {
- header = "Проверка материала";
- MySQLConnector dbCon = MySQLConnector.Instance();
-
- articleClone = await dbCon.SQLSelectArticle(DocID);
- article = (ArticleModel)articleClone.Clone();
- string initiator = await article.GetInitiatorUUID(ArticleStatus.Saved);
- initiatorAcc = AccountModel.Find(initiator);
- status = $"Article ID={DocID} loaded, status: {article.Status}, initiator: {initiatorAcc.Name}";
- }
- else
- header = "Загрузка материала";
- //await InitializeAccount();
- //int count = await articleModel.GetEditsCount();
- //int countbyid = await articleModel.GetEditsCount(currentAcc.UUID);
- //header += $", uuid:{currentAcc.UUID}, name: {currentAcc.Name}, edits count:{count}, count by accid: {countbyid}";
- }
- public async Task<string> NewProjectSmopp(long articleId)
- {
- WebRequest wrGETURL;
- wrGETURL = WebRequest.Create("http://dev.prmsys.net/makeproject.php?pt=232&aid="+ articleId);
- var response = await wrGETURL.GetResponseAsync();
- Stream dataStream = response.GetResponseStream();
- StreamReader reader = new(dataStream);
- return reader.ReadToEnd();
- }
- private async Task HandleSubmit()
- {
- Console.WriteLine($"HandleSubmit, docID: {DocID}.");
- modalLoading.Open();
- /// form validation
- List<string> errorFields = ValidateForm<ArticleModel>(article);
- if (errorFields.Count > 0)
- {
- modalLoading.Close();
- string invalid_fields = string.Join(", ", errorFields);
- modalInfo_error.Open($"Не заполнены поля: {invalid_fields}");
- Console.WriteLine($"HandleSubmit. Required fields: '{invalid_fields}' is not filled.");
- return;
- }
- /// all is fine, continue
- MySQLConnector dbCon = MySQLConnector.Instance();
- long id;
- string stringSQL;
- if (DocID > 0)
- {
- id = DocID;
- stringSQL = $"UPDATE articles " +
- $"SET filename='{article.Filename}', article_name='{article.Name}', authors='{article.Authors}', " +
- $"date_publish='{article.PublishDate:yyyy-MM-dd}', annotation='{article.Annotation}', " +
- $"keywords='{article.Keywords}', rating={article.Rating}, file_hash='{article.HashSum}' " +
- $"WHERE id={DocID}";
- await dbCon.SQLInsert(stringSQL);
- }
- else
- {
- stringSQL = $"INSERT INTO articles (filename, article_name, authors, date_publish, annotation, keywords, file_hash) " +
- $"VALUES ('{article.Filename}', '{article.Name}', '{article.Authors}', '{article.PublishDate:yyyy-MM-dd}'," +
- $"'{article.Annotation}', '{article.Keywords}', '{article.HashSum}')";
- id = await dbCon.SQLInsert(stringSQL);
- NewProjectSmopp(id);
- }
- /// tmp
- int action_type = DocID > 0 ? 2 : 1;
- stringSQL = $"INSERT INTO actions_history (article_id, action_type, acc_id) " +
- $"VALUES ('{id}', '{action_type}', '{currentAcc.UUID}')";
- await dbCon.SQLInsert(stringSQL);
- Dictionary<string, PropertyInfo> propDict = Compare.SimpleCompare<ArticleModel>(article, articleClone);
- foreach (KeyValuePair<string, PropertyInfo> prop in propDict)
- {
- //Console.WriteLine($"property name: {prop.Key}, value: {prop.Value.GetValue(articleModel, null)}");
- stringSQL = $"INSERT INTO articles_edit_log (article_id, acc_id, field_name, field_prevvalue, field_newvalue) " +
- $"VALUES ('{id}', '{currentAcc.UUID}', '{prop.Key}', '{prop.Value.GetValue(articleClone, null)}', '{prop.Value.GetValue(article, null)}')";
- await dbCon.SQLInsert(stringSQL);
- }
- //dbCon.Close();
- if (DocID > 0)
- {
- status = propDict.Count > 0 ? "All changes saved, article has veryfied." : "Article verifyed without any changes.";
- //transactionId = await Verify();
- Console.WriteLine("transactionId found " + transactionId);
- ///tmp
- editsCount = await article.GetEditsCount(currentAcc.UUID);
- modalInfo_transac.Open("");
- }
- else
- {
- string fullpath = Path.Combine(storageFolderPath, $"{id}_{article.Filename}");
- Directory.CreateDirectory(storageFolderPath);
- FileStream fs = new(fullpath, FileMode.Create, FileAccess.Write);
- memoryStream.Position = 0;
- await memoryStream.CopyToAsync(fs);
- Console.WriteLine($"User has saved new article data, {id}_{article.Filename}, memory size:{memoryStream.Length}b, file size: {fs.Length}b");
- memoryStream.Close();
- fs.Close();
- status = "New article data saved.";
- bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Хотите загрузить еще статью?");
- if (confirmed)
- NavigationManager.NavigateTo("docedit", true);
- else
- NavigationManager.NavigateTo("");
- }
- /// reloading articles
- await AppData.LoadArticles();
- }
- private async Task HandleSelection(InputFileChangeEventArgs e)
- {
- modalLoading.Open();
- IBrowserFile file = e.File;
- if (file != null)
- {
- Stream stream = file.OpenReadStream(MAX_FILE_SIZE);
- memoryStream = new();
- await stream.CopyToAsync(memoryStream);
- status = $"Finished loading {memoryStream.Length} bytes from {file.Name}";
- Console.WriteLine(status);
- /// calculating hash
- string hash = await CalculateHashSum(memoryStream);
- Console.WriteLine($"Hash: {hash}");
- /// checking hash
- MySQLConnector dbCon = MySQLConnector.Instance();
- string stringSQL;
- stringSQL = $"SELECT COUNT(*) FROM articles WHERE file_hash='{hash}'";
- int count = await dbCon.SQLSelectCount(stringSQL);
- //Console.WriteLine($"File duplicate check, founded files: {count}");
- if (count < 1)
- {
- //articleClone = DocParse.GetBaseProperties(memoryStream);
- articleClone = DocParse.GetBaseProperties("");
- articleClone.Filename = file.Name;
- articleClone.HashSum = hash;
- article = (ArticleModel)articleClone.Clone();
- IsSubmitDisabled = false;
- }
- else
- {
- status = $"File duplicate founded, hash: {hash}.";
- Console.WriteLine(status);
- IsSubmitDisabled = true;
- memoryStream.Close();
- stream.Close();
- modalInfo_error.Open("Загрузка не удалась, такой документ уже есть в системе.");
- }
- }
- modalLoading.Close();
- }
- private async Task Cancel()
- {
- bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Вы уверены, что хотите отклонить статью?");
- if (confirmed)
- {
- ///какая-то логика отмены...
- NavigationManager.NavigateTo("");
- }
- }
- //public async Task InitializeAccount()
- //{
- // AccountModel.Current = await GetCurrentAcc();
- // Console.WriteLine("InitializeAccount in DocEdit " + AccountModel.Current.Name);
- //}
- private async Task<AccountModel> GetCurrentAcc()
- {
- AccountModel account = new();
- var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
- var user = authState.User;
- if (user.Identity.IsAuthenticated)
- {
- var currentUser = await UserManager.GetUserAsync(user);
- account.UUID = currentUser.Id;
- //account.Name = currentUser.UserName;
- //account.Email = currentUser.Email;
- var acc = AccountModel.Find(account.UUID);
- if (acc != null)
- account = acc;
- ///tmp
- //account.AccRole = Role.User;
- return account;
- }
- return null;
- }
- private async Task<string> CalculateHashSum(MemoryStream ms)
- {
- MD5CryptoServiceProvider md5Provider = new();
- ms.Position = 0;
- byte[] hash = await md5Provider.ComputeHashAsync(ms);
- return Convert.ToBase64String(hash);
- }
- private List<string> ValidateForm<T>(T obj)
- {
- var props = typeof(T).GetProperties().Where(pi => Attribute.IsDefined(pi, typeof(RequiredAttribute)));
- List<string> result = new();
- foreach (var prop in props)
- {
- var val = prop.GetValue(obj, null);
- if (val == null || val?.ToString().Length == 0)
- result.Add(prop.Name);
- //Console.WriteLine($"Required field '{prop.Name}' is not filled.");
- }
- return result;
- }
- }
- }
|