123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812 |
- using HyperCube.Models;
- using Microsoft.AspNetCore.Components;
- using Microsoft.AspNetCore.Components.Authorization;
- using Microsoft.AspNetCore.Components.Forms;
- using Microsoft.AspNetCore.Identity;
- using Microsoft.JSInterop;
- using Pullenti.Unitext;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel.DataAnnotations;
- using System.IO;
- using System.Linq;
- using System.Reflection;
- using System.Security.Cryptography;
- using System.Text;
- using System.Threading.Tasks;
- using System.Xml;
- using Console = HyperCube.Utils.AdvConsole;
- namespace HyperCube.Pages
- {
- public partial class Desktop : ComponentBase
- {
- //[Parameter]
- //public int DocID { get; set; }
- [Inject]
- NavigationManager NavigationManager { get; set; }
- [Inject]
- AuthenticationStateProvider AuthenticationStateProvider { get; set; }
- [Inject]
- UserManager<IdentityUser> UserManager { get; set; }
- [Inject]
- RoleManager<IdentityRole> RoleManager { get; set; }
- [Inject]
- AppData AppData { get; set; }
- [Inject]
- public IJSRuntime JsRuntime { get; set; }
- const string STORAGE_FOLDER_NAME = "articles_storage";
- const long MAX_FILE_SIZE = 5120000; //bytes
- const string ACTIVE_BUTTON_CLASS = "btn_white tab-button active";
- const string ACTIVE_TAB_CLASS = "second-block__form visible";
- const string BUTTON_CLASS = "btn_white tab-button";
- const string TAB_CLASS = "second-block__form";
- string _uploadButtonClass = ACTIVE_BUTTON_CLASS;
- string _uploadTabClass = ACTIVE_TAB_CLASS;
- string _verifyButtonClass = BUTTON_CLASS;
- string _verifyTabClass = TAB_CLASS;
- string _otherButtonClass = BUTTON_CLASS;
- string _otherTabClass = TAB_CLASS;
- int _counter = 1;
- //string _event = "";
- string _status;
- string _articleDropdownOption = "";
- //string _storageFolderPath;
- MemoryStream _memoryStream;
- ModalInfo _modalInfo { get; set; }
- ModalLoading _modalLoading { get; set; }
- ArticleModel _articleClone;
- ArticleModel _article;
- Dictionary<int, ArticleModel> _articles = new();
- ReportModel _report = new();
- UnitextDocument _document;
- AccountModel _currentAccount;
- VerificationPoint _verificationPoint = new();
- bool loadButtonDisable { get; set; }
- bool verifyButtonDisable { get; set; }
- bool rejectReasonDisable { get; set; }
- protected override async Task OnInitializedAsync()
- {
- _currentAccount = (AppData.CurrentAccount != null) ? AppData.CurrentAccount : await GetCurrentAcc();
- _currentAccount.LoadRoles();
- Console.WriteLine($"Desktop OnInitializedAsync, CurrentAccount: {_currentAccount.Name}");
- ///tmp
- await LoadArticles();
- _article = AppData.CurrentArticle ?? (new());
- _articleClone = AppData.CurrentArticleClone ?? (new());
- }
- protected override void OnAfterRender(bool firstRender) => _counter = 1;
- void SwitchDesktopTab(int tabIndex)
- {
- switch(tabIndex)
- {
- case 0:
- _uploadButtonClass = ACTIVE_BUTTON_CLASS;
- _uploadTabClass = ACTIVE_TAB_CLASS;
- _verifyButtonClass = BUTTON_CLASS;
- _verifyTabClass = TAB_CLASS;
- _otherButtonClass = BUTTON_CLASS;
- _otherTabClass = TAB_CLASS;
- break;
- case 1:
- _uploadButtonClass = BUTTON_CLASS;
- _uploadTabClass = TAB_CLASS;
- _verifyButtonClass = ACTIVE_BUTTON_CLASS;
- _verifyTabClass = ACTIVE_TAB_CLASS;
- _otherButtonClass = BUTTON_CLASS;
- _otherTabClass = TAB_CLASS;
- break;
- case 2:
- _uploadButtonClass = BUTTON_CLASS;
- _uploadTabClass = TAB_CLASS;
- _verifyButtonClass = BUTTON_CLASS;
- _verifyTabClass = TAB_CLASS;
- _otherButtonClass = ACTIVE_BUTTON_CLASS;
- _otherTabClass = ACTIVE_TAB_CLASS;
- break;
- }
- }
- async Task WidgetMenuClick(string menuname, string elementid)
- {
- await JsRuntime.InvokeVoidAsync("WidgetMenuClick", menuname, elementid);
- _counter = 1;
- }
- async Task HandleUpload(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);
- if (count < 1)
- {
- _report = new();
- _report.FileName = file.Name;
- _report.FileSize = _memoryStream.Length.ToString();
- _memoryStream.Position = 0;
- byte[] content = _memoryStream.ToArray();
- _document = UnitextService.CreateDocument(null, content, null);
- if (_document.ErrorMessage != null)
- {
- // скорее всего, этот формат не поддерживается на данный момент
- Console.WriteLine($"error, sorry: {_document.ErrorMessage}");
- _memoryStream.Close();
- stream.Close();
- _modalLoading.Close();
- _modalInfo.Open("Не удается прочитать документ, формат не поддерживается или файл поврежден.");
- return;
- }
- // восстанавливаем имя исходного файла, извлечённого из ресурсов
- _document.SourceFileName = file.Name;
- for (int i = file.Name.Length - 7; i > 0; i--)
- {
- if (file.Name[i] == '.')
- {
- _document.SourceFileName = file.Name.Substring(i + 1);
- break;
- }
- }
- //// записываем результат в XML
- //using (FileStream fs = new(doc.SourceFileName + ".xml", FileMode.Create, FileAccess.Write))
- //{
- // XmlWriterSettings xmlParams = new();
- // xmlParams.Encoding = Encoding.UTF8;
- // xmlParams.Indent = true;
- // xmlParams.IndentChars = " ";
- // using (XmlWriter xml = XmlWriter.Create(fs, xmlParams))
- // {
- // xml.WriteStartDocument();
- // doc.GetXml(xml);
- // xml.WriteEndDocument();
- // }
- //}
- //Console.WriteLine("XML write done");
- // получаем плоский текст
- string plainText = _document.GetPlaintextString(null);
- if (plainText == null)
- plainText = "Текст не выделен";
- /// todo обработка, если статус != новый
- _articleClone = DocParse.GetBaseProperties(plainText);
- _articleClone.Filename = file.Name;
- _articleClone.HashSum = hash;
- _article = (ArticleModel)_articleClone.Clone();
- ///tmp
- AppData.CurrentArticle = _article;
- Console.WriteLine($"Initializing SDK Pullenti ver {Pullenti.Sdk.Version} ({Pullenti.Sdk.VersionDate})... ");
- Pullenti.Sdk.InitializeAll();
- //Console.WriteLine($"OK (by ... ms), version {Pullenti.Ner.ProcessorService.Version}");
- List<string> npt_tokens = new();
- // запускаем обработку на пустом процессоре (без анализаторов NER)
- Pullenti.Ner.AnalysisResult are = Pullenti.Ner.ProcessorService.EmptyProcessor.Process(new Pullenti.Ner.SourceOfAnalysis(plainText), null, null);
- //System.Console.Write("Noun groups: ");
- // перебираем токены
- for (Pullenti.Ner.Token t = are.FirstToken; t != null; t = t.Next)
- {
- // выделяем именную группу с текущего токена
- Pullenti.Ner.Core.NounPhraseToken npt = Pullenti.Ner.Core.NounPhraseHelper.TryParse(t, Pullenti.Ner.Core.NounPhraseParseAttr.No, 0, null);
- // не получилось
- if (npt == null)
- continue;
- // получилось, выводим в нормализованном виде
- //System.Console.Write($"[{npt.GetSourceText()}=>{npt.GetNormalCaseText(null, Pullenti.Morph.MorphNumber.Singular, Pullenti.Morph.MorphGender.Undefined, false)}] ");
- //_report.NounGroups += $"[{npt.GetSourceText()}=>{npt.GetNormalCaseText(null, Pullenti.Morph.MorphNumber.Singular, Pullenti.Morph.MorphGender.Undefined, false)}] ";
- _article.NounGroups += $"[{npt.GetSourceText()}=>{npt.GetNormalCaseText(null, Pullenti.Morph.MorphNumber.Singular, Pullenti.Morph.MorphGender.Undefined, false)}] ";
- npt_tokens.Add(npt.GetNormalCaseText(null, Pullenti.Morph.MorphNumber.Singular, Pullenti.Morph.MorphGender.Undefined, false));
- // указатель на последний токен именной группы
- t = npt.EndToken;
- }
- using (Pullenti.Ner.Processor proc = Pullenti.Ner.ProcessorService.CreateProcessor())
- {
- // анализируем текст
- Pullenti.Ner.AnalysisResult ar = proc.Process(new Pullenti.Ner.SourceOfAnalysis(plainText), null, null);
- // результирующие сущности
- //Console.WriteLine("\r\n==========================================\r\nEntities: ");
- foreach (Pullenti.Ner.Referent en in ar.Entities)
- {
- //Console.WriteLine($"{en.TypeName}: {en}");
- //_report.Entities += $"{en.TypeName}: {en}\r\n";
- _article.Entities += $"{en.TypeName}: {en}\r\n";
- foreach (Pullenti.Ner.Slot s in en.Slots)
- {
- //Console.WriteLine($" {s.TypeName}: {s.Value}");
- //_report.Entities += $" {s.TypeName}: {s.Value}<br>";
- _article.Entities += $" {s.TypeName}: {s.Value}<br>";
- }
- }
- // пример выделения именных групп
- //Console.WriteLine("\r\n==========================================\r\nNoun groups: ");
- for (Pullenti.Ner.Token t = ar.FirstToken; t != null; t = t.Next)
- {
- // токены с сущностями игнорируем
- if (t.GetReferent() != null)
- continue;
- // пробуем создать именную группу
- Pullenti.Ner.Core.NounPhraseToken npt = Pullenti.Ner.Core.NounPhraseHelper.TryParse(t, Pullenti.Ner.Core.NounPhraseParseAttr.AdjectiveCanBeLast, 0, null);
- // не получилось
- if (npt == null)
- continue;
- //Console.WriteLine(npt.ToString());
- //_report.EntitiesNounGroups += $"{npt}<br>";
- _article.Morph += $"{npt}<br>";
- // указатель перемещаем на последний токен группы
- t = npt.EndToken;
- }
- }
- using (Pullenti.Ner.Processor proc = Pullenti.Ner.ProcessorService.CreateSpecificProcessor(Pullenti.Ner.Keyword.KeywordAnalyzer.ANALYZER_NAME))
- {
- Pullenti.Ner.AnalysisResult ar = proc.Process(new Pullenti.Ner.SourceOfAnalysis(plainText), null, null);
- //Console.WriteLine("\r\n==========================================\r\nKeywords1: ");
- foreach (Pullenti.Ner.Referent en in ar.Entities)
- {
- if (en is Pullenti.Ner.Keyword.KeywordReferent)
- //Console.WriteLine(en.ToString());
- //_report.Keywords1 += $"{en}<br>";
- _article.Keywords1 += $"{en}<br>";
- }
- //Console.WriteLine("\r\n==========================================\r\nKeywords2: ");
- for (Pullenti.Ner.Token t = ar.FirstToken; t != null; t = t.Next)
- {
- if (t is Pullenti.Ner.ReferentToken)
- {
- Pullenti.Ner.Keyword.KeywordReferent kw = t.GetReferent() as Pullenti.Ner.Keyword.KeywordReferent;
- if (kw == null)
- continue;
- string kwstr = Pullenti.Ner.Core.MiscHelper.GetTextValueOfMetaToken(t as Pullenti.Ner.ReferentToken, Pullenti.Ner.Core.GetTextAttr.FirstNounGroupToNominativeSingle | Pullenti.Ner.Core.GetTextAttr.KeepRegister);
- //Console.WriteLine($"{kwstr} = {kw}");
- //_report.Keywords2 += $"{kwstr} = {kw}<br>";
- _article.Keywords2 += $"{kwstr} = {kw}<br>";
- }
- }
- }
-
- int res = (from x in npt_tokens
- select x).Distinct().Count();
- Console.WriteLine($"npt_tokens.count={npt_tokens.Count}, distinct.Count={res}");
- Console.WriteLine("Analysis is over!");
- var query = from x in npt_tokens
- group x by x into g
- let count1 = g.Count()
- orderby count1 descending
- select new { Name = g.Key, Count = count1 };
- foreach (var result in query)
- {
- _report.NounGroupsSorted += $"{result.Name}, Count: {result.Count}<br>";
- //Console.WriteLine($"Name: {result.Name}, Count: {result.Count}");
- }
- //AppData.Report = _report;
- }
- else
- {
- _status = $"File duplicate founded, hash: {hash}.";
- Console.WriteLine(_status);
- _article = new();
- _articleClone = new();
- _document = null;
- _memoryStream.Close();
- _modalInfo.Open("Загрузка не удалась, такой документ уже есть в системе.");
- }
- file = null;
- stream.Close();
- }
- _modalLoading.Close();
- }
- async Task NewDocument()
- {
- _article = new();
- _articleClone = new();
- _document = null;
- _memoryStream = null;
- _status = "Blank document created";
- await JsRuntime.InvokeVoidAsync("WidgetMenuClick", ".block__dropbox", "desktop_menu");
- _counter = 1;
- }
- async Task SaveDocument_OnClick(ArticleStatus articleNewStatus)
- {
- Console.WriteLine($"SaveDocument_OnClick. DocID: {_article.ID}, Status: {_article.Status}");
- if (_article.Name == null || _article.Name.Length == 0)
- {
- Console.WriteLine($"SaveDocument, empty article name. DocID: {_article.ID}, Status: {_article.Status}, filename: {_article.Filename}");
- _modalInfo.Open( $"Для сохранения документа необходимо ввести название.");
- return;
- }
- if (_article.Status == ArticleStatus.New && _memoryStream == null)
- {
- Console.WriteLine($"SaveDocument, empty source file. DocID: {_article.ID}, Status: {_article.Status}, filename: {_article.Filename}");
- _modalInfo.Open($"Для сохранения документа необходимо прикрепить исходный файл.");
- return;
- }
- if (_article.Status == ArticleStatus.New && articleNewStatus == ArticleStatus.Verifying
- || _article.Status == ArticleStatus.AwatingVerify && articleNewStatus == ArticleStatus.Saved
- || _article.Status == ArticleStatus.Verifying && articleNewStatus == ArticleStatus.Saved
- || _article.Status == ArticleStatus.Verified && articleNewStatus == ArticleStatus.Saved
- || _article.Status == ArticleStatus.Verified && articleNewStatus == ArticleStatus.Verifying)
- {
- Console.WriteLine($"SaveDocument, wrong status. DocID: {_article.ID}, Status: {_article.Status}");
- _modalInfo.Open($"Текущий статус документа не позволяет сохранение.<br>DocID: {_article.ID}, Status: {GetDisplayName(_article.Status)}");
- }
- else
- {
- /// all is fine, continue
- MySQLConnector dbCon = MySQLConnector.Instance();
- long id;
- string stringSQL;
- if (_article.Status == ArticleStatus.New)
- {
- _modalLoading.Open();
- stringSQL = $"INSERT INTO articles (filename, article_name, authors, date_publish, annotation, keywords, file_hash, " +
- $"doc_noungroups, doc_entities, doc_morph, doc_keywords1, doc_keywords2) " +
- $"VALUES ('{_article.Filename}', '{_article.Name}', '{_article.Authors}', '{_article.PublishDate:yyyy-MM-dd}'," +
- $"'{_article.Annotation}', '{_article.Keywords}', '{_article.HashSum}'," +
- $"'{_article.NounGroups}', '{_article.Entities}', '{_article.Morph}', '{_article.Keywords1}', '{_article.Keywords2}' )";
- id = await dbCon.SQLInsert(stringSQL);
- _article.ID = (int)id;
- ///todo добавлять новый док в массив AppData.Articles
- stringSQL = $"INSERT INTO actions_history (article_id, action_type, acc_id) " +
- $"VALUES ('{id}', '{(int)articleNewStatus}', '{_currentAccount.UUID}')";
- await dbCon.SQLInsert(stringSQL);
- await SaveFiles((int)id);
-
- _article.Status = ArticleStatus.Saved;
- _articleClone = (ArticleModel)_article.Clone();
- /// reloading articles
- await LoadArticles();
- _counter = 1;
- _modalLoading.Close();
- _modalInfo.Open("Документ успешно создан.");
- }
- else
- {
- await UpdateDocument(articleNewStatus);
- //await SaveFiles(_article.ID);
- if (_article.Status == ArticleStatus.AwatingVerify || _article.Status == ArticleStatus.Verifying)
- await _article.SaveLastVerificationPoint(_verificationPoint, _currentAccount.UUID);
- }
- }
- }
- async Task LoadDocument(int docid)
- {
- ///todo загружать из массива AppData.Articles
- Console.WriteLine($"LoadDocument, docid: {docid}.");
- _modalLoading.Open();
- if (docid > 0)
- {
- MySQLConnector dbCon = MySQLConnector.Instance();
- string stringSQL = $"SELECT articles.id, filename, article_name, authors, date_publish, annotation, keywords, action_type, rating, file_hash, " +
- $"doc_noungroups, doc_entities, doc_morph, doc_keywords1, doc_keywords2 " +
- $"FROM articles " +
- $"JOIN actions_history ON actions_history.article_id = articles.id " +
- $"WHERE articles.id={docid} " +
- $"ORDER BY actions_history.id DESC LiMIT 1";
-
- AppData.CurrentArticleClone = await dbCon.SQLSelectArticle(stringSQL);
- await AppData.CurrentArticleClone.GetVerificationHistory(_currentAccount.UUID);
- if (AppData.CurrentArticleClone.VerificationHistory.Count > 0)
- _verificationPoint = AppData.CurrentArticleClone.VerificationHistory.Values.Last();
- else
- _verificationPoint = new();
- AppData.CurrentArticle = (ArticleModel)AppData.CurrentArticleClone.Clone();
- //string initiator = await _article.GetInitiatorUUID();
- //initiatorAcc = AccountModel.Find(initiator);
- //_status = $"Article ID={DocID} loaded, status: {_article.Status}, initiator: {initiatorAcc.Name}";
- _status = $"Article ID={docid} loaded, status: {AppData.CurrentArticle.Status}.";
- _article = AppData.CurrentArticle ?? (new());
- _articleClone = AppData.CurrentArticleClone ?? (new());
- }
- _modalLoading.Close();
- }
- async Task SendToVerify_OnClick()
- {
- if (_article.Status == ArticleStatus.New || _article.Status == ArticleStatus.Saved)
- {
- Console.WriteLine($"SendToVerify, DocID: {_article.ID}, Status: {_article.Status}");
- _modalLoading.Open();
- /// form validation
- List<string> errorFields = ValidateForm<ArticleModel>(_article);
- if (errorFields.Count > 0)
- {
- _modalLoading.Close();
- string invalid_fields = string.Join(", ", errorFields);
- _modalInfo.Open($"Не заполнены поля: {invalid_fields}");
- Console.WriteLine($"SendToVerify. Required fields: '{invalid_fields}' is not filled.");
- return;
- }
- await UpdateDocument(ArticleStatus.AwatingVerify);
- _modalLoading.Close();
- }
- else
- {
- Console.WriteLine($"SendToVerify, wrong status. DocID: {_article.ID}, Status: {_article.Status}");
- _modalInfo.Open($"Документ не может быть отправлен на верификацию.<br>DocID: {_article.ID}, Status: {GetDisplayName(_article.Status)}");
- }
- }
- async Task Verify_OnClick()
- {
- //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();
- //}
- if (_article.Status == ArticleStatus.AwatingVerify || _article.Status == ArticleStatus.Verifying)
- {
- Console.WriteLine($"Verify, DocID: {_article.ID}, Status: {_article.Status}");
- _modalLoading.Open();
- /// form validation
- List<string> errorFields = ValidateForm<ArticleModel>(_article);
- if (errorFields.Count > 0)
- {
- _modalLoading.Close();
- string invalid_fields = string.Join(", ", errorFields);
- _modalInfo.Open($"Не заполнены поля: {invalid_fields}");
- Console.WriteLine($"Verify. Required fields: '{invalid_fields}' is not filled.");
- return;
- }
- var bcMain = await _currentAccount.GetSelectedBlockChain();
- var transactionId = await bcMain.Verify(_currentAccount, _article);
- Console.WriteLine("transactionId found " + transactionId);
- await UpdateDocument(ArticleStatus.Verified);
- _modalLoading.Close();
- }
- else
- {
- Console.WriteLine($"Verify, wrong status. DocID: {_article.ID}, Status: {_article.Status}");
- _modalInfo.Open($"Документ не может быть верифицирован.<br>DocID: {_article.ID}, Status: {GetDisplayName(_article.Status)}");
- }
- }
- async Task UpdateDocument(ArticleStatus articleStatus)
- {
- _modalLoading.Open();
- MySQLConnector dbCon = MySQLConnector.Instance();
- string stringSQL;
- string rating = (_article.Rating == null) ? "NULL" : _article.Rating.ToString();
- 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={rating}, file_hash='{_article.HashSum}' " +
- $"WHERE id={_article.ID}";
- await dbCon.SQLInsert(stringSQL);
- ///todo обновлять док в массиве AppData.Articles
- stringSQL = $"INSERT INTO actions_history (article_id, action_type, acc_id) " +
- $"VALUES ('{_article.ID}', '{(int)articleStatus}', '{_currentAccount.UUID}')";
- await dbCon.SQLInsert(stringSQL);
- ///если нужно фиксировать изменение статуса в поле (табл articles_edit_log)
- //_article.Status = articleStatus;
- 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 ('{_article.ID}', '{_currentAccount.UUID}', '{prop.Key}', '{prop.Value.GetValue(_articleClone, null)}', '{prop.Value.GetValue(_article, null)}')";
- await dbCon.SQLInsert(stringSQL);
- }
- _article.Status = articleStatus;
- _articleClone = (ArticleModel)_article.Clone();
- /// reloading articles
- await LoadArticles();
- _modalLoading.Close();
- string message = propDict.Count > 0 ? "Все изменения успешно сохранены." : "Изменений не найдено.";
- _modalInfo.Open(message);
- }
- async Task DocSelect_OnChange(ChangeEventArgs e)
- {
- int docid = int.Parse(e.Value.ToString());
- Console.WriteLine($"DocSelect_OnChange. docid: {docid}");
- await LoadDocument(docid);
- }
- async Task SaveFiles(int docid)
- {
- if (_document != null )
- {
- string fullpath;
- string htmldirectorypath;
- string docdirectorypath;
- #if DEBUG
- htmldirectorypath = Path.Combine(Environment.CurrentDirectory, "wwwroot", STORAGE_FOLDER_NAME, "html");
- docdirectorypath = Path.Combine(Environment.CurrentDirectory, "wwwroot", STORAGE_FOLDER_NAME, "source");
- #else
- htmldirectorypath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot", STORAGE_FOLDER_NAME, "html");
- docdirectorypath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot", STORAGE_FOLDER_NAME, "source");
- #endif
- try
- {
- /// получаем html, сохраняем файлы
- GetHtmlParam htmlParams = new();
- htmlParams.OutHtmlAndBodyTags = true;
- string html = _document.GetHtmlString(htmlParams);
- ///saving html
- fullpath = Path.Combine(htmldirectorypath, $"{docid}_{_document.SourceFileName}.html");
- Console.WriteLine($"Saving file [{fullpath}]");
- Directory.CreateDirectory(htmldirectorypath);
- File.WriteAllBytes(fullpath, Encoding.UTF8.GetBytes(html));
- }
- catch (Exception ex)
- {
- Console.WriteLine($"{ex.GetType()}\r\n{ex.Message}\r\n{ex.StackTrace}");
- }
- ///saving original files
- fullpath = Path.Combine(docdirectorypath, $"{docid}_{_article.Filename}");
- Console.WriteLine($"Saving file [{fullpath}]");
- Directory.CreateDirectory(docdirectorypath);
- FileStream fs = new(fullpath, FileMode.Create, FileAccess.Write);
- _memoryStream.Position = 0;
- await _memoryStream.CopyToAsync(fs);
- _status = $"User has saved new article data: [{docid}_{_article.Filename}], memory size:{_memoryStream.Length}b, file size: {fs.Length}b";
- Console.WriteLine(_status);
- _memoryStream.Close();
- fs.Close();
- _document = null;
- }
- }
- async Task GetArticleFile(string option)
- {
- string fullpath;
- string htmldirectorypath;
- string docdirectorypath;
- #if DEBUG
- htmldirectorypath = Path.Combine(Environment.CurrentDirectory, "wwwroot", STORAGE_FOLDER_NAME, "html");
- docdirectorypath = Path.Combine(Environment.CurrentDirectory, "wwwroot", STORAGE_FOLDER_NAME, "source");
- #else
- htmldirectorypath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot", STORAGE_FOLDER_NAME, "html");
- docdirectorypath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wwwroot", STORAGE_FOLDER_NAME, "source");
- #endif
- if (option == "source")
- {
- fullpath = Path.Combine(docdirectorypath, $"{_article.ID}_{_article.Filename}");
- if (fullpath.Length > 0 && File.Exists(fullpath))
- NavigationManager.NavigateTo($"{STORAGE_FOLDER_NAME}/source/{_article.ID}_{_article.Filename}", true);
- else
- {
- Console.WriteLine($"GetArticleFile, file not exists: [{fullpath}].");
- _modalInfo.Open("Файл документа не найден.");
- }
- }
-
- else if (option == "html")
- {
- fullpath = Path.Combine(docdirectorypath, $"{_article.ID}_{_article.Filename}.html");
- if (fullpath.Length > 0 && File.Exists(fullpath))
- NavigationManager.NavigateTo($"{STORAGE_FOLDER_NAME}/html/{_article.ID}_{_article.Filename}.html", true);
- else
- {
- Console.WriteLine($"GetArticleFile, file not exists: [{fullpath}].");
- _modalInfo.Open("Файл документа не найден.");
- }
- }
- else
- {
- Console.WriteLine($"GetArticleFile, unknown method option: [{option}].");
- //return;
- }
- }
- void Rejected_OnChange()
- {
- rejectReasonDisable = !_verificationPoint.Rejected;
- }
- async Task LoadArticles()
- {
- /// reloading articles
- await AppData.LoadArticles();
- _articles = new();
- ///updating local articles and UI on role claims
- if (_currentAccount.Roles.Contains(Role.Admin))
- {
- loadButtonDisable = false;
- verifyButtonDisable = false;
- _articles = AppData.Articles;
- }
- else if (_currentAccount.Roles.Contains(Role.Expert))
- {
- loadButtonDisable = true;
- verifyButtonDisable = false;
- foreach (ArticleModel article in AppData.Articles.Values)
- {
- if (article.Status == ArticleStatus.AwatingVerify || article.Status == ArticleStatus.Verifying)
- _articles.Add(article.ID, article);
- }
- SwitchDesktopTab(1);
- }
- else if (_currentAccount.Roles.Contains(Role.Miner))
- {
- loadButtonDisable = false;
- verifyButtonDisable = true;
- foreach (ArticleModel article in AppData.Articles.Values)
- {
- if (article.Status == ArticleStatus.New || article.Status == ArticleStatus.Saved)
- _articles.Add(article.ID, article);
- }
- }
- else
- {
- loadButtonDisable = true;
- verifyButtonDisable = true;
- _articles = AppData.Articles;
- SwitchDesktopTab(2);
- }
- }
- async Task<string> CalculateHashSum(MemoryStream ms)
- {
- MD5CryptoServiceProvider md5Provider = new();
- ms.Position = 0;
- byte[] hash = await md5Provider.ComputeHashAsync(ms);
- return Convert.ToBase64String(hash);
- }
- 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;
- }
- static string GetDisplayName(Enum enumValue)
- {
- return enumValue.GetType()
- .GetMember(enumValue.ToString())
- .First()
- .GetCustomAttribute<DisplayAttribute>()
- .GetName();
- }
- async Task<AccountModel> GetCurrentAcc()
- {
- Console.WriteLine($"Desktop GetCurrentAcc");
- if (_currentAccount == null)
- {
- var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
- var user = authState.User;
- if (user.Identity.IsAuthenticated)
- {
- var currentUser = await UserManager.GetUserAsync(user);
- var acc = AccountModel.Find(currentUser.Id);
- if (acc != null)
- {
- _currentAccount = AccountModel.Loaded[currentUser.Id];
- }
- else
- {
- Dictionary<string, AccountModel> accounts = await MySQLConnector.Instance().SQLSelectASPUsers();
- if (accounts.ContainsKey(currentUser.Id))
- _currentAccount = accounts[currentUser.Id];
- }
- /// asp roles
- //var role1 = new IdentityRole { Name = "admin" };
- //var result = await RoleManager.CreateAsync(role1);
- //Console.WriteLine($"RoleManager create result: {result}");
- //result = await UserManager.AddToRoleAsync(currentUser, role1.Name);
- //Console.WriteLine($"RoleManager add role result: {result}");
- }
- }
- return _currentAccount;
- }
- }
- }
|