Sfoglia il codice sorgente

editing article, changes logger

ganahrhr 4 anni fa
parent
commit
8c2eb5bbc7
3 ha cambiato i file con 106 aggiunte e 43 eliminazioni
  1. 30 0
      Compare.cs
  2. 10 2
      Models/ArticleModel.cs
  3. 66 41
      Pages/DocEdit.razor

+ 30 - 0
Compare.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+namespace HyperCube
+{
+    public static class Compare
+    {
+        public static Dictionary<string, PropertyInfo> SimpleCompare<T>(T object1, T object2)
+        {
+            var props = typeof(T).GetProperties().Where(pi => pi.CanRead);
+            Dictionary<string, PropertyInfo> result = new();
+            foreach (var prop in props)
+            {
+                var val1 = prop.GetValue(object1, null);
+                var val2 = prop.GetValue(object2, null);
+                if (prop.PropertyType == typeof(DateTime))
+                {
+                    TimeSpan timeSpan = (DateTime)val1 - (DateTime)val2;
+                    if (timeSpan.TotalDays != 0)
+                        result[prop.Name] = prop;
+                }
+                else if (val1 != val2)
+                    result[prop.Name] = prop;
+            }
+            return result;
+        }
+    }
+}

+ 10 - 2
Models/ArticleModel.cs

@@ -3,13 +3,15 @@ using System.ComponentModel.DataAnnotations;
 
 namespace HyperCube.Models
 {
-    public class ArticleModel
+    public enum ArticleStatus { New = 0, Added, Edited, Verified, Rejected, Deleted }
+
+    public class ArticleModel : ICloneable
     {
         public string Filename { get; set; }
         [Required]        
         public string Name { get; set; }        
         [Required]
-        public DateTime PublishDate { get; set; } = DateTime.Now;
+        public DateTime PublishDate { get; set; } = DateTime.Now.Date;
         [Required]
         public string Authors { get; set; }
         [Required]
@@ -17,5 +19,11 @@ namespace HyperCube.Models
         [Required]
         public string Annotation { get; set; }
         public string Text { get; set; }
+        public ArticleStatus Status { get; set; } = ArticleStatus.New;
+
+        public object Clone()
+        {
+            return MemberwiseClone();
+        }
     }
 }

+ 66 - 41
Pages/DocEdit.razor

@@ -1,5 +1,6 @@
 @page "/docedit"
 @page "/docedit/{docID:int}"
+@using System.Reflection;
 @using HyperCube.Models;
 @inject NavigationManager NavigationManager;
 @inject IJSRuntime JsRuntime;
@@ -50,8 +51,10 @@
 
     const string FOLDER_NAME = "articles_storage";
     const long MAX_FILE_SIZE = 5120000; //bytes
+    const int ACC_ID = 1; //temp
 
-    ArticleModel articleModel = new ArticleModel();
+    ArticleModel oldArticleModel = new();
+    ArticleModel articleModel = new();
     string status;
     string header;
     string storageFolderPath;
@@ -68,8 +71,11 @@
 
             MySQLConnector dbCon = MySQLConnector.Instance();
 
-            string stringSQL = $"SELECT id, filename, article_name, authors, date_publish, annotation, keywords FROM articles WHERE id={docID}";
-            articleModel = await dbCon.SQLSelectArticle(stringSQL);
+            string stringSQL = $"SELECT id, filename, article_name, authors, date_publish, annotation, keywords " +
+                $"FROM articles " +
+                $"WHERE id={docID}";
+            oldArticleModel = await dbCon.SQLSelectArticle(stringSQL);
+            articleModel = (ArticleModel)oldArticleModel.Clone();
 
             status = $"Article ID={docID} loaded.";
         }
@@ -80,36 +86,68 @@
     private async void HandleValidSubmit()
     {
         MySQLConnector dbCon = MySQLConnector.Instance();
+        long id = 0;
+        string stringSQL;
 
-        string stringSQL = $"INSERT INTO articles (filename, article_name, authors, date_publish, annotation, keywords)" +
-            $"VALUES ('{articleModel.Filename}', '{articleModel.Name}', '{articleModel.Authors}', '{articleModel.PublishDate.ToString("yyyy-MM-dd")}'," +
-            $"'{articleModel.Annotation}', '{articleModel.Keywords}')";
-        long id = dbCon.SQLInsert(stringSQL);
+        if (docID > 0)
+        {
+            id = docID;
+            stringSQL = $"UPDATE articles " +
+                $"SET filename='{articleModel.Filename}', article_name='{articleModel.Name}', authors='{articleModel.Authors}', " +
+                    $"date_publish='{articleModel.PublishDate.ToString("yyyy-MM-dd")}', annotation='{articleModel.Annotation}', keywords='{articleModel.Keywords}' " +
+                $"WHERE id={docID}";
+            dbCon.SQLInsert(stringSQL);
+        }
+        else
+        {
+            stringSQL = $"INSERT INTO articles (filename, article_name, authors, date_publish, annotation, keywords) " +
+                $"VALUES ('{articleModel.Filename}', '{articleModel.Name}', '{articleModel.Authors}', '{articleModel.PublishDate.ToString("yyyy-MM-dd")}'," +
+                $"'{articleModel.Annotation}', '{articleModel.Keywords}')";
+            id = dbCon.SQLInsert(stringSQL);
+        }
 
-        stringSQL = $"INSERT INTO actions_history (article_id, action_type, acc_id)" +
-            $"VALUES ('{id}', {1}, {1})";
-        dbCon.SQLInsert(stringSQL);
+        int action_type = docID > 0 ? 2 : 1;
 
-        dbCon.Close();
+        stringSQL = $"INSERT INTO actions_history (article_id, action_type, acc_id) " +
+            $"VALUES ('{id}', '{action_type}', '{ACC_ID}')";
+        dbCon.SQLInsert(stringSQL);
 
-        //Console.WriteLine($"memorystream: {memoryStream.Length}, filename: {articleModel.Filename}");
-        string fullpath = Path.Combine(storageFolderPath, $"{id}_{articleModel.Filename}");
-        Directory.CreateDirectory(storageFolderPath);
-        FileStream fs = new(fullpath, FileMode.Create, FileAccess.Write);
-        memoryStream.Position = 0;
-        await memoryStream.CopyToAsync(fs);
+        Dictionary<string, PropertyInfo> propDict = Compare.SimpleCompare<ArticleModel>(articleModel, oldArticleModel);
+        foreach (KeyValuePair<string, PropertyInfo> prop in propDict)
+        {
+            //Console.WriteLine($"property name: {prop.Key}, value: {prop.Value.GetValue(articleModel, null)}");
 
-        Console.WriteLine($"User has saved new article data, {id}_{articleModel.Filename}, memory size:{memoryStream.Length}b, file size: {fs.Length}b");
-        memoryStream.Close();
-        fs.Close();
+            stringSQL = $"INSERT INTO articles_edit_log (article_id, acc_id, field_name, field_prevvalue, field_newvalue) " +
+                $"VALUES ('{id}', '{ACC_ID}', '{prop.Key}', '{prop.Value.GetValue(oldArticleModel, null)}', '{prop.Value.GetValue(articleModel, null)}')";
+            dbCon.SQLInsert(stringSQL);
+        }
 
-        status = "New article data saved.";
+        dbCon.Close();
 
-        bool confirmed = await JsRuntime.InvokeAsync<bool>("confirm", "Хотите загрузить еще статью?");
-        if (confirmed)
-            NavigationManager.NavigateTo("docedit", true);
+        if (docID > 0)
+        {
+            status = propDict.Count > 0 ? "All changes saved, article has veryfied." : "Article verifyed without any changes.";
+        }
         else
-            NavigationManager.NavigateTo("");
+        {
+            string fullpath = Path.Combine(storageFolderPath, $"{id}_{articleModel.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}_{articleModel.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("");
+        }
     }
 
     private async Task HandleSelection(InputFileChangeEventArgs e)
@@ -123,8 +161,9 @@
             status = $"Finished loading {memoryStream.Length} bytes from {file.Name}";
 
             DocParse docParse = new DocParse();
-            articleModel = DocParse.ReadPDF(memoryStream);
-            articleModel.Filename = file.Name;
+            oldArticleModel = DocParse.ReadPDF(memoryStream);
+            oldArticleModel.Filename = file.Name;
+            articleModel = (ArticleModel)oldArticleModel.Clone();
         }
     }
 
@@ -137,18 +176,4 @@
             NavigationManager.NavigateTo("");
         }
     }
-
-    //private async void DownloadDoc()
-    //{
-    //    string fullpath = Path.Combine(storageFolderPath, $"{docID}_{articleModel.Filename}");
-    //    if (File.Exists(fullpath))
-    //    {
-    //        //await JsRuntime.InvokeAsync<string>("downloadFile", fullpath);
-    //    }
-    //    else
-    //    {
-    //        Console.WriteLine($"File {fullpath} not found.");
-    //        status = $"File {fullpath} not found.";
-    //    }
-    //}
 }