Browse Source

survey engine&editor part2

ganahrhr 2 năm trước cách đây
mục cha
commit
f095754bf8
5 tập tin đã thay đổi với 162 bổ sung53 xóa
  1. 110 6
      Models/Survey.cs
  2. 4 4
      MySQLConnector.cs
  3. 34 24
      Pages/SurveyEditor.razor
  4. 12 17
      Pages/SurveyEditor.razor.cs
  5. 2 2
      Pages/Surveys.razor

+ 110 - 6
Models/Survey.cs

@@ -17,6 +17,7 @@ namespace HyperCube.Models
         public string CreatorID { get; set; }
         public Dictionary<int, SurveyItem> SurveyItems { get; set; } = new();
         public bool IsNew { get; set; } = true;
+        public bool IsDeleted { get; set; } = false;
 
         public async Task<int> Save(string userID)
         {
@@ -25,21 +26,45 @@ namespace HyperCube.Models
 
             if (IsNew)
             {
-                ///tmp
-                EvenID = 1;
-
                 stringSQL = $"INSERT INTO surveys (eventid, name, description, creatorid) " +
                     $"VALUES ({EvenID}, '{Name}', '{Description}', '{userID}')";
             }
             else
             {
                 stringSQL = $"UPDATE surveys " +
-                    $"SET eventid={EvenID}, name='{Name}', description='{Description}' " + // creatorid='{userID}'
+                    $"SET eventid={EvenID}, name='{Name}', description='{Description}', deleted={Convert.ToInt32(IsDeleted)} " +
                     $"WHERE id={ID}";
             }
 
             newID = await MySQLConnector.Instance().SQLInsert(stringSQL);
             IsNew = false;
+
+            int newItemID;
+            Dictionary<int, SurveyItem> tmpSurveyItems = new();
+            foreach (var item in SurveyItems)
+            {
+                if (newID != 0)
+                    item.Value.SurveyID = (int)newID;                
+
+                newItemID = await item.Value.Save(userID);                
+                if (newItemID != 0 && item.Key != newItemID)
+                {
+                    Console.WriteLine($"Adding and updating item id: [{item.Key}] with new id: [{newItemID}]");
+                    tmpSurveyItems.Add(newItemID, item.Value);
+                }
+                else
+                {
+                    Console.WriteLine($"Adding existed item id: [{item.Key}]");
+                    tmpSurveyItems.Add(item.Key, item.Value);
+                }                
+            }
+
+            if (tmpSurveyItems.Count > 0)
+            {
+                SurveyItems.Clear();
+                SurveyItems = tmpSurveyItems.ToDictionary(entry => entry.Key, entry => (SurveyItem)entry.Value.Clone());
+            }
+
             return ID = (int)newID;
         }
 
@@ -60,9 +85,54 @@ namespace HyperCube.Models
             };
             SurveyItems.Add(newTempKey, item);
         }
+
+        public void DeleteItem(int itemID)
+        {
+            if (SurveyItems.Count > 0 && SurveyItems.ContainsKey(itemID))
+            {
+                Console.WriteLine($"Survey:[{ID}] DeleteItem id: [{SurveyItems[itemID].ID}] - isnew: {SurveyItems[itemID].IsNew}");
+
+                if (SurveyItems[itemID].IsNew)
+                    SurveyItems.Remove(itemID);
+                else
+                    SurveyItems[itemID].IsDeleted = true;
+            }
+        }
+
+        public void MoveItem(int itemID, int step)
+        {
+            if (SurveyItems.Count > 0 && SurveyItems.ContainsKey(itemID))
+            {
+                Console.WriteLine($"Survey:[{ID}] MoveItem id: [{SurveyItems[itemID].ID}]");
+
+                int min = SurveyItems.Select(o => o.Value.Position).Min();
+                int max = SurveyItems.Select(o => o.Value.Position).Max();
+
+                Console.WriteLine($"min:{min}, max:{max}.");
+
+                int oldPosition, newPosition;
+                oldPosition = SurveyItems[itemID].Position;
+
+                int targetPosition = (oldPosition + step < min) ? min : oldPosition + step;
+                targetPosition = (oldPosition + step > max) ? max : oldPosition + step;
+
+                Console.WriteLine($"oldPosition:{oldPosition}, step:{step}, target:{targetPosition}.");
+
+                int targetKey = SurveyItems.FirstOrDefault(x => x.Value.Position == targetPosition).Key;
+                //SurveyItems.TryGetValue(targetPosition, out SurveyItem targetItem);
+                if (targetKey != 0)
+                {
+                    newPosition = SurveyItems[targetKey].Position;
+                    Console.WriteLine($"newPosition:{newPosition}.");
+
+                    SurveyItems[itemID].Position = newPosition;
+                    SurveyItems[targetKey].Position = oldPosition;
+                }
+            }
+        }
     }
 
-    public class SurveyItem
+    public class SurveyItem : ICloneable
     {
         public int ID { get; set; }
         public int SurveyID { get; set; }
@@ -75,6 +145,29 @@ namespace HyperCube.Models
         public Dictionary<int, SurveyItemOption> SurveyItemOptions { get; set; } = new();
         public int AnswerID { get; set; } /// SurveyItemOption selected ID
         public bool IsNew { get; set; } = true;
+        public bool IsDeleted { get; set; } = false;
+
+        public async Task<int> Save(string userID)
+        {
+            long newID;
+            string stringSQL;
+
+            if (IsNew)
+            {
+                stringSQL = $"INSERT INTO surveyitems (surveyid, itemtext, position, required, creatorid) " +
+                    $"VALUES ({SurveyID}, '{Text}', {Position}, {Convert.ToInt32(Required)}, '{userID}')";
+            }
+            else
+            {
+                stringSQL = $"UPDATE surveyitems " +
+                    $"SET surveyid={SurveyID}, itemtext='{Text}', position={Position}, required={Convert.ToInt32(Required)}, deleted={Convert.ToInt32(IsDeleted)} " +
+                    $"WHERE id={ID}";
+            }
+
+            newID = await MySQLConnector.Instance().SQLInsert(stringSQL);
+            IsNew = false;
+            return ID = (int)newID;
+        }
 
         public void AddNewOption(string userID)
         {
@@ -93,9 +186,14 @@ namespace HyperCube.Models
             };
             SurveyItemOptions.Add(newTempKey, option);
         }
+
+        public object Clone()
+        {
+            return MemberwiseClone();
+        }
     }
 
-    public class SurveyItemOption
+    public class SurveyItemOption : ICloneable
     {
         public int ID { get; set; }
         public int ItemID { get; set; }
@@ -109,5 +207,11 @@ namespace HyperCube.Models
         public DateTime DateCreated { get; set; }
         public DateTime DateUpdated { get; set; }
         public bool IsNew { get; set; } = true;
+        public bool IsDeleted { get; set; } = false;
+
+        public object Clone()
+        {
+            return MemberwiseClone();
+        }
     }
 }

+ 4 - 4
MySQLConnector.cs

@@ -59,12 +59,11 @@ namespace HyperCube
             bool connected = await IsConnect();
             if (connected)
             {
-                MySqlCommand SQLcom3 = new(sql, Connection);
-                //SQLcom3.ExecuteNonQuery();
+                MySqlCommand SQLcom3 = new(sql, Connection);                
                 await SQLcom3.ExecuteNonQueryAsync();
                 lastID = SQLcom3.LastInsertedId;
                 SQLcom3.Dispose();
-                Console.WriteLine($"SQLInsert end");
+                //Console.WriteLine($"SQLInsert end");
             }
             else
                 Console.WriteLine("Not connected to DB.");
@@ -224,7 +223,8 @@ namespace HyperCube
 
         public async Task<List<Dictionary<string, object>>> SQLSelectComplex(string request, bool check = true)
         {
-            Console.WriteLine($"SQLSelectComplex {request}");
+            if (request != "select COUNT(*) from accounts")
+                Console.WriteLine($"SQLSelectComplex {request}");
             bool connected = true;
             if (check)
             {

+ 34 - 24
Pages/SurveyEditor.razor

@@ -2,7 +2,7 @@
 @page "/surveyeditor/{ID:int}"
 
 <div style="margin-left:20px">
-    <h3>Редактор опросов (тестовая квалификаци)</h3>
+    <h3>Редактор опросов (тестовая квалификация)</h3>
 
     <div style="margin:10px; margin-left:0px">
         <a href="surveys">Вернуться к списку опросов</a>
@@ -28,33 +28,43 @@
             @*<div>id: @item.Key</div>*@
             <div>
                 Вопрос №@item.Value.Position
-                <a style="cursor:pointer" @onclick="ItemMoveUp">&#11014;</a>
-                <a style="cursor:pointer" @onclick="ItemMoveDown">&#11015;</a>
-                <a style="cursor:pointer" @onclick="ItemDelete">&#10006;</a>
+                <a style="cursor:pointer" @onclick="(() => ItemMove(item.Key, -1))">&#11014;</a>
+                <a style="cursor:pointer" @onclick="(() => ItemMove(item.Key, 1))">&#11015;</a>
+                <a style="cursor:pointer" @onclick="(() => ItemDelete(item.Key))">&#10006;</a>
             </div>
             <div>
-                <InputTextArea type="text" @bind-Value="item.Value.Text" placeholder="Введете текст вопроса" />                
+                <InputTextArea type="text" @bind-Value="item.Value.Text" placeholder="Введете текст вопроса" />
+            </div>
+            <div style="margin-left:20px">
+                @foreach (var option in item.Value.SurveyItemOptions)
+                {
+                    if (!option.Value.IsDeleted)
+                    {
+                        <div>
+                            Ответ №@option.Value.Position
+                            <a style="cursor:pointer" @onclick="OptionMove">&#11014;</a>
+                            <a style="cursor:pointer" @onclick="OptionMove">&#11015;</a>
+                            <a style="cursor:pointer" @onclick="OptionDelete">&#10006;</a>
+                        </div>
+                        <div>
+                            <InputText type="text" @bind-Value="option.Value.Text" placeholder="Введите текст ответа" />
+                        </div>
+                        <div>
+                            П - <InputNumber @bind-Value="option.Value.Rate1" style="width:40px; text-align:center" />
+                            М - <InputNumber @bind-Value="option.Value.Rate2" style="width:40px; text-align:center" />
+                            Л - <InputNumber @bind-Value="option.Value.Rate3" style="width:40px; text-align:center" />
+                            С - <InputNumber @bind-Value="option.Value.Rate4" style="width:40px; text-align:center" />
+                        </div>
+                    }
+                }
+                <div style="margin-left:20px; cursor:pointer" @onclick="(() => AddNewOption(item.Key))">+ Добавить вариант ответа</div>
             </div>
-            @foreach (var option in item.Value.SurveyItemOptions)
-            {
-                <div>
-                    Ответ №@option.Value.Position
-                    <a style="cursor:pointer" @onclick="OptionMoveUp">&#11014;</a>
-                    <a style="cursor:pointer" @onclick="OptionMoveDown">&#11015;</a>
-                    <a style="cursor:pointer" @onclick="OptionDelete">&#10006;</a>
-                </div>
-                <div>
-                    <InputText type="text" @bind-Value="option.Value.Text" placeholder="Введите текст ответа" />
-                </div>
-                <div>
-                    П - <InputNumber @bind-Value="option.Value.Rate1" style="width:40px; text-align:center" />
-                    М - <InputNumber @bind-Value="option.Value.Rate2" style="width:40px; text-align:center" />
-                    Л - <InputNumber @bind-Value="option.Value.Rate3" style="width:40px; text-align:center" />
-                    С - <InputNumber @bind-Value="option.Value.Rate4" style="width:40px; text-align:center" />
-                </div>
-            }
-            <div style="margin-left:20px; cursor:pointer" @onclick="(() => AddNewOption(item.Key))">+ Добавить вариант ответа</div>
         }
         <div style="cursor:pointer" @onclick="(() => AddNewItem())">+ Добавить вопрос</div>
     </EditForm>
 </div>
+
+<ModalInfo @ref="_modalInfo">
+    <Title></Title>
+    <Body></Body>
+</ModalInfo>

+ 12 - 17
Pages/SurveyEditor.razor.cs

@@ -25,6 +25,8 @@ namespace HyperCube.Pages
         AccountModel _currentAccount;
         Survey _survey = new();
 
+        ModalInfo _modalInfo;
+
         protected override async Task OnInitializedAsync()
         {
             _currentAccount = await GetCurrentAcc();
@@ -51,7 +53,7 @@ namespace HyperCube.Pages
                 SurveyItem item;
                 SurveyItemOption option;                
 
-                var surveyItems = await MySQLConnector.Instance().SQLSelectComplex($"SELECT * FROM surveyitems WHERE surveyid={_survey.ID} ORDER BY position");
+                var surveyItems = await MySQLConnector.Instance().SQLSelectComplex($"SELECT * FROM surveyitems WHERE surveyid={_survey.ID} AND deleted<>1 ORDER BY position");
                 if (surveyItems.Count > 0)
                 {
                     foreach (var i in surveyItems)
@@ -70,7 +72,7 @@ namespace HyperCube.Pages
                         };
                         Console.WriteLine($"SurveyEditor. load survey items id: {item.ID}, position: {item.Position}, name: {item.Text}");
 
-                        var surveyItemOption = await MySQLConnector.Instance().SQLSelectComplex($"SELECT * FROM surveyitemoptions WHERE itemid={item.ID} ORDER BY position");
+                        var surveyItemOption = await MySQLConnector.Instance().SQLSelectComplex($"SELECT * FROM surveyitemoptions WHERE itemid={item.ID} AND deleted<>1 ORDER BY position");
                         if (surveyItemOption.Count > 0)
                         {
                             foreach (var o in surveyItemOption)
@@ -105,28 +107,20 @@ namespace HyperCube.Pages
 
         void AddNewOption(int ItemID) => _survey.SurveyItems[ItemID].AddNewOption(_currentAccount.UUID);
 
-        void NewSurvey()
-        {
-            NavigationManager.NavigateTo("surveyeditor", true);
-        }
-
-        void ItemMoveUp()
-        {
-        }
-
-        void ItemMoveDown()
-        {
-        }
+        void NewSurvey() => NavigationManager.NavigateTo("surveyeditor", true);
 
-        void ItemDelete()
+        void ItemMove(int itemID, int step)
         {
+            _survey.MoveItem(itemID, step);
         }
 
-        void OptionMoveUp()
+        void ItemDelete(int itemID)
         {
+            _survey.DeleteItem(itemID);
+            StateHasChanged();
         }
 
-        void OptionMoveDown()
+        void OptionMove()
         {
         }
 
@@ -137,6 +131,7 @@ namespace HyperCube.Pages
         async Task SaveSurvey()
         {
             await _survey.Save(_currentAccount.UUID);
+            _modalInfo.Open("Опрос сохранен.");
         }
 
         async Task<AccountModel> GetCurrentAcc()

+ 2 - 2
Pages/Surveys.razor

@@ -42,7 +42,7 @@
     {
         Survey survey;
 
-        var surveys = await MySQLConnector.Instance().SQLSelectComplex($"SELECT * FROM surveys;");
+        var surveys = await MySQLConnector.Instance().SQLSelectComplex($"SELECT * FROM surveys WHERE deleted<>1");
         if (surveys.Count > 0)
         {
             foreach (var s in surveys)
@@ -58,7 +58,7 @@
                     CreatorID = Convert.ToString(s["creatorid"])
                 };
 
-                Console.WriteLine($"add survey. id: {survey.ID}, name: {survey.Name}");
+                //Console.WriteLine($"add survey. id: {survey.ID}, name: {survey.Name}");
                 _surveys.Add(survey.ID, survey);
             }
         }