DocEdit.razor 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. @page "/docedit"
  2. @page "/docedit/{docID:int}"
  3. @using System.Reflection;
  4. @using HyperCube.Models;
  5. @inject NavigationManager NavigationManager;
  6. @inject IJSRuntime JsRuntime;
  7. @attribute [Authorize]
  8. @*@attribute [Authorize(Roles = "admin")]*@
  9. @inject AuthenticationStateProvider AuthenticationStateProvider
  10. @using Microsoft.AspNetCore.Identity;
  11. @inject UserManager<IdentityUser> UserManager;
  12. <EditForm Model="@articleModel" OnValidSubmit="@HandleValidSubmit">
  13. <DataAnnotationsValidator />
  14. <ValidationSummary />
  15. <h1>@header</h1>
  16. <br>
  17. <div style="width: 50%;">
  18. @if (docID < 1)
  19. {
  20. <p><InputFile id="inputDefault" OnChange="@HandleSelection" accept="application/pdf" /></p>
  21. //accept="application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document"
  22. }
  23. else
  24. {
  25. <p>Исходный документ: <a href=@FOLDER_NAME download="@articleModel.Filename" target="_top">@articleModel.Filename</a></p>
  26. }
  27. <p><InputText id="article_name" class="form-control" @bind-Value="articleModel.Name" placeholder="Наименование статьи" /></p>
  28. <p><InputDate id="date_publish" class="form-control" @bind-Value="articleModel.PublishDate" placeholder="Дата издания" /></p>
  29. <p><InputText id="author" class="form-control" @bind-Value="articleModel.Authors" placeholder="Автор" /></p>
  30. <p><InputTextArea id="keywords" class="form-control" @bind-Value="articleModel.Keywords" placeholder="Ключевые слова" /></p>
  31. <p><InputTextArea rows="5" id="annotation" class="form-control" @bind-Value="articleModel.Annotation" placeholder="Аннотация" /></p>
  32. <p><InputTextArea rows="10" id="text" class="form-control" @bind-Value="articleModel.Text" placeholder="Текст" /></p>
  33. @if (docID < 1)
  34. {
  35. <p><button class="btn btn-primary" type="submit">Загрузить</button></p>
  36. }
  37. else
  38. {
  39. @*<p>
  40. <InputRadioGroup @bind-Value="articleModel.Status">
  41. Оценка:
  42. <br>
  43. @foreach (var status in (ArticleStatus[])Enum.GetValues(typeof(ArticleStatus)))
  44. {
  45. <InputRadio Value="status" />
  46. @status
  47. <br />
  48. }
  49. </InputRadioGroup>
  50. </p>*@
  51. <p>
  52. <InputRadioGroup @bind-Value="articleModel.Rating">
  53. Оценка:
  54. <br>
  55. @for (int i = 1; i < 6; i++)
  56. {
  57. <InputRadio Value="i" />
  58. @i
  59. <br />
  60. }
  61. </InputRadioGroup>
  62. </p>
  63. <p>
  64. <button class="btn btn-danger" type="button" @onclick="@Cancel">Отклонить</button>
  65. <button @onclick="Verify" class="btn btn-primary" type="submit">Утвердить</button>
  66. </p>
  67. }
  68. <p>Статус: @status</p>
  69. </div>
  70. </EditForm>
  71. @code {
  72. [Parameter]
  73. public int docID { get; set; }
  74. const string FOLDER_NAME = "articles_storage";
  75. const long MAX_FILE_SIZE = 5120000; //bytes
  76. //const int ACC_ID = 1; //temp
  77. ArticleModel oldArticleModel = new();
  78. ArticleModel articleModel = new();
  79. AccountModel currentAcc = new();
  80. string status;
  81. string header;
  82. string storageFolderPath;
  83. MemoryStream memoryStream;
  84. async Task Verify()
  85. {
  86. try
  87. {
  88. VerifyContract verifyContract = SmartContract.Find("Verify") as VerifyContract;
  89. if (verifyContract != null)
  90. {
  91. Console.WriteLine($"VerifyContract found");
  92. await verifyContract.Run(articleModel);
  93. }
  94. else
  95. Console.WriteLine($"VerifyContract null");
  96. }
  97. catch (Exception e)
  98. {
  99. Console.WriteLine(e.Message + "stack trace" + e.StackTrace);
  100. }
  101. }
  102. protected override async Task OnInitializedAsync()
  103. {
  104. currentAcc = await GetCurrentAcc();
  105. string path = AppDomain.CurrentDomain.BaseDirectory;
  106. storageFolderPath = (Path.Combine(path, FOLDER_NAME));
  107. if (docID > 0)
  108. {
  109. header = "Проверка материала";
  110. MySQLConnector dbCon = MySQLConnector.Instance();
  111. string stringSQL = $"SELECT articles.id, filename, article_name, authors, date_publish, annotation, keywords, action_type, rating " +
  112. $"FROM articles " +
  113. $"JOIN actions_history ON actions_history.article_id = articles.id " +
  114. $"WHERE articles.id={docID} " +
  115. $"ORDER BY actions_history.id DESC LiMIT 1";
  116. oldArticleModel = await dbCon.SQLSelectArticle(stringSQL);
  117. articleModel = (ArticleModel)oldArticleModel.Clone();
  118. string initiator = await articleModel.GetInitiatorUUID();
  119. status = $"Article ID={docID} loaded, status: {articleModel.Status}, initiatorUUID: {await articleModel.GetInitiatorUUID()}";
  120. }
  121. else
  122. header = "Загрузка материала";
  123. InitializeAccount();
  124. //int count = await articleModel.GetEditsCount();
  125. //int countbyid = await articleModel.GetEditsCount(currentAcc.UUID);
  126. //header += $", uuid:{currentAcc.UUID}, name: {currentAcc.Name}, edits count:{count}, count by accid: {countbyid}";
  127. }
  128. private async void HandleValidSubmit()
  129. {
  130. MySQLConnector dbCon = MySQLConnector.Instance();
  131. long id = 0;
  132. string stringSQL;
  133. if (docID > 0)
  134. {
  135. id = docID;
  136. stringSQL = $"UPDATE articles " +
  137. $"SET filename='{articleModel.Filename}', article_name='{articleModel.Name}', authors='{articleModel.Authors}', " +
  138. $"date_publish='{articleModel.PublishDate.ToString("yyyy-MM-dd")}', annotation='{articleModel.Annotation}', " +
  139. $"keywords='{articleModel.Keywords}', rating={articleModel.Rating} " +
  140. $"WHERE id={docID}";
  141. dbCon.SQLInsert(stringSQL);
  142. }
  143. else
  144. {
  145. stringSQL = $"INSERT INTO articles (filename, article_name, authors, date_publish, annotation, keywords) " +
  146. $"VALUES ('{articleModel.Filename}', '{articleModel.Name}', '{articleModel.Authors}', '{articleModel.PublishDate.ToString("yyyy-MM-dd")}'," +
  147. $"'{articleModel.Annotation}', '{articleModel.Keywords}')";
  148. id = dbCon.SQLInsert(stringSQL);
  149. }
  150. ///temp
  151. int action_type = docID > 0 ? 2 : 1;
  152. stringSQL = $"INSERT INTO actions_history (article_id, action_type, acc_id) " +
  153. $"VALUES ('{id}', '{action_type}', '{currentAcc.UUID}')";
  154. dbCon.SQLInsert(stringSQL);
  155. Dictionary<string, PropertyInfo> propDict = Compare.SimpleCompare<ArticleModel>(articleModel, oldArticleModel);
  156. foreach (KeyValuePair<string, PropertyInfo> prop in propDict)
  157. {
  158. //Console.WriteLine($"property name: {prop.Key}, value: {prop.Value.GetValue(articleModel, null)}");
  159. stringSQL = $"INSERT INTO articles_edit_log (article_id, acc_id, field_name, field_prevvalue, field_newvalue) " +
  160. $"VALUES ('{id}', '{currentAcc.UUID}', '{prop.Key}', '{prop.Value.GetValue(oldArticleModel, null)}', '{prop.Value.GetValue(articleModel, null)}')";
  161. dbCon.SQLInsert(stringSQL);
  162. }
  163. dbCon.Close();
  164. if (docID > 0)
  165. {
  166. status = propDict.Count > 0 ? "All changes saved, article has veryfied." : "Article verifyed without any changes.";
  167. }
  168. else
  169. {
  170. string fullpath = Path.Combine(storageFolderPath, $"{id}_{articleModel.Filename}");
  171. Directory.CreateDirectory(storageFolderPath);
  172. FileStream fs = new(fullpath, FileMode.Create, FileAccess.Write);
  173. memoryStream.Position = 0;
  174. await memoryStream.CopyToAsync(fs);
  175. Console.WriteLine($"User has saved new article data, {id}_{articleModel.Filename}, memory size:{memoryStream.Length}b, file size: {fs.Length}b");
  176. memoryStream.Close();
  177. fs.Close();
  178. status = "New article data saved.";
  179. bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Хотите загрузить еще статью?");
  180. if (confirmed)
  181. NavigationManager.NavigateTo("docedit", true);
  182. else
  183. NavigationManager.NavigateTo("");
  184. }
  185. }
  186. private async Task HandleSelection(InputFileChangeEventArgs e)
  187. {
  188. IBrowserFile file = e.File;
  189. if (file != null)
  190. {
  191. Stream stream = file.OpenReadStream(MAX_FILE_SIZE);
  192. memoryStream = new();
  193. await stream.CopyToAsync(memoryStream);
  194. status = $"Finished loading {memoryStream.Length} bytes from {file.Name}";
  195. DocParse docParse = new DocParse();
  196. oldArticleModel = DocParse.ReadPDF(memoryStream);
  197. oldArticleModel.Filename = file.Name;
  198. articleModel = (ArticleModel)oldArticleModel.Clone();
  199. }
  200. }
  201. private async void Cancel()
  202. {
  203. bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Вы уверены, что хотите отклонить статью?");
  204. if (confirmed)
  205. {
  206. ///какая-то логика отмены...
  207. NavigationManager.NavigateTo("");
  208. }
  209. }
  210. public async void InitializeAccount()
  211. {
  212. AccountModel.Current = await GetCurrentAcc();
  213. Console.WriteLine("InitializeAccount in DocEdit "+ AccountModel.Current.Name);
  214. }
  215. private async Task<AccountModel> GetCurrentAcc()
  216. {
  217. AccountModel account = new();
  218. var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
  219. var user = authState.User;
  220. if (user.Identity.IsAuthenticated)
  221. {
  222. var currentUser = await UserManager.GetUserAsync(user);
  223. account.UUID = currentUser.Id;
  224. //account.Name = currentUser.UserName;
  225. //account.Email = currentUser.Email;
  226. var acc = AccountModel.Find(account.UUID);
  227. if (acc != null)
  228. account = acc;
  229. ///tmp
  230. account.AccRole = Role.User;
  231. return account;
  232. }
  233. return null;
  234. }
  235. }